]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/i386/mmx.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / i386 / mmx.md
1 ;; GCC machine description for MMX and 3dNOW! instructions
2 ;; Copyright (C) 2005-2021 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")
556 (vec_concat:V2SF
557 (plus:SF
558 (vec_select:SF
559 (match_operand:V2SF 1 "register_operand" "0")
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")
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 "pfacc\t{%2, %0|%0, %2}"
573 [(set_attr "type" "mmxadd")
574 (set_attr "prefix_extra" "1")
575 (set_attr "mode" "V2SF")])
576
577 (define_insn "*mmx_haddv2sf3_low"
578 [(set (match_operand:SF 0 "register_operand" "=x,x")
579 (plus:SF
580 (vec_select:SF
581 (match_operand:V2SF 1 "register_operand" "0,x")
582 (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))
583 (vec_select:SF
584 (match_dup 1)
585 (parallel [(match_operand:SI 3 "const_0_to_1_operand")]))))]
586 "TARGET_MMX_WITH_SSE && TARGET_SSE3
587 && INTVAL (operands[2]) != INTVAL (operands[3])"
588 "@
589 haddps\t{%0, %0|%0, %0}
590 vhaddps\t{%1, %1, %0|%0, %1, %1}"
591 [(set_attr "isa" "noavx,avx")
592 (set_attr "type" "sseadd1")
593 (set_attr "prefix" "orig,vex")
594 (set_attr "mode" "V4SF")])
595
596 (define_insn "mmx_hsubv2sf3"
597 [(set (match_operand:V2SF 0 "register_operand" "=y")
598 (vec_concat:V2SF
599 (minus:SF
600 (vec_select:SF
601 (match_operand:V2SF 1 "register_operand" "0")
602 (parallel [(const_int 0)]))
603 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
604 (minus:SF
605 (vec_select:SF
606 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
607 (parallel [(const_int 0)]))
608 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
609 "TARGET_3DNOW_A"
610 "pfnacc\t{%2, %0|%0, %2}"
611 [(set_attr "type" "mmxadd")
612 (set_attr "prefix_extra" "1")
613 (set_attr "mode" "V2SF")])
614
615 (define_insn "*mmx_hsubv2sf3_low"
616 [(set (match_operand:SF 0 "register_operand" "=x,x")
617 (minus:SF
618 (vec_select:SF
619 (match_operand:V2SF 1 "register_operand" "0,x")
620 (parallel [(const_int 0)]))
621 (vec_select:SF
622 (match_dup 1)
623 (parallel [(const_int 1)]))))]
624 "TARGET_MMX_WITH_SSE && TARGET_SSE3"
625 "@
626 hsubps\t{%0, %0|%0, %0}
627 vhsubps\t{%1, %1, %0|%0, %1, %1}"
628 [(set_attr "isa" "noavx,avx")
629 (set_attr "type" "sseadd1")
630 (set_attr "prefix" "orig,vex")
631 (set_attr "mode" "V4SF")])
632
633 (define_expand "mmx_haddsubv2sf3"
634 [(set (match_operand:V2SF 0 "register_operand")
635 (vec_concat:V2SF
636 (minus:SF
637 (vec_select:SF
638 (match_operand:V2SF 1 "register_operand")
639 (parallel [(const_int 0)]))
640 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
641 (plus:SF
642 (vec_select:SF
643 (match_operand:V2SF 2 "nonimmediate_operand")
644 (parallel [(const_int 0)]))
645 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))]
646 "TARGET_3DNOW_A")
647
648 (define_insn "*mmx_haddsubv2sf3"
649 [(set (match_operand:V2SF 0 "register_operand" "=y")
650 (vec_concat:V2SF
651 (minus:SF
652 (vec_select:SF
653 (match_operand:V2SF 1 "register_operand" "0")
654 (parallel [(const_int 0)]))
655 (vec_select:SF (match_dup 1) (parallel [(const_int 1)])))
656 (plus:SF
657 (vec_select:SF
658 (match_operand:V2SF 2 "nonimmediate_operand" "ym")
659 (parallel [(match_operand:SI 3 "const_0_to_1_operand")]))
660 (vec_select:SF
661 (match_dup 2)
662 (parallel [(match_operand:SI 4 "const_0_to_1_operand")])))))]
663 "TARGET_3DNOW_A
664 && INTVAL (operands[3]) != INTVAL (operands[4])"
665 "pfpnacc\t{%2, %0|%0, %2}"
666 [(set_attr "type" "mmxadd")
667 (set_attr "prefix_extra" "1")
668 (set_attr "mode" "V2SF")])
669
670 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
671 ;;
672 ;; Parallel single-precision floating point comparisons
673 ;;
674 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
675
676 (define_expand "mmx_eqv2sf3"
677 [(set (match_operand:V2SI 0 "register_operand")
678 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand")
679 (match_operand:V2SF 2 "nonimmediate_operand")))]
680 "TARGET_3DNOW"
681 "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);")
682
683 (define_insn "*mmx_eqv2sf3"
684 [(set (match_operand:V2SI 0 "register_operand" "=y")
685 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0")
686 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
687 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
688 "pfcmpeq\t{%2, %0|%0, %2}"
689 [(set_attr "type" "mmxcmp")
690 (set_attr "prefix_extra" "1")
691 (set_attr "mode" "V2SF")])
692
693 (define_insn "mmx_gtv2sf3"
694 [(set (match_operand:V2SI 0 "register_operand" "=y")
695 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
696 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
697 "TARGET_3DNOW"
698 "pfcmpgt\t{%2, %0|%0, %2}"
699 [(set_attr "type" "mmxcmp")
700 (set_attr "prefix_extra" "1")
701 (set_attr "mode" "V2SF")])
702
703 (define_insn "mmx_gev2sf3"
704 [(set (match_operand:V2SI 0 "register_operand" "=y")
705 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
706 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
707 "TARGET_3DNOW"
708 "pfcmpge\t{%2, %0|%0, %2}"
709 [(set_attr "type" "mmxcmp")
710 (set_attr "prefix_extra" "1")
711 (set_attr "mode" "V2SF")])
712
713 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
714 ;;
715 ;; Parallel single-precision floating point logical operations
716 ;;
717 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
718
719 (define_insn "*mmx_andnotv2sf3"
720 [(set (match_operand:V2SF 0 "register_operand" "=x,x")
721 (and:V2SF
722 (not:V2SF
723 (match_operand:V2SF 1 "register_operand" "0,x"))
724 (match_operand:V2SF 2 "register_operand" "x,x")))]
725 "TARGET_MMX_WITH_SSE"
726 "@
727 andnps\t{%2, %0|%0, %2}
728 vandnps\t{%2, %1, %0|%0, %1, %2}"
729 [(set_attr "isa" "noavx,avx")
730 (set_attr "type" "sselog")
731 (set_attr "prefix" "orig,vex")
732 (set_attr "mode" "V4SF")])
733
734 (define_insn "*mmx_<code>v2sf3"
735 [(set (match_operand:V2SF 0 "register_operand" "=x,x")
736 (any_logic:V2SF
737 (match_operand:V2SF 1 "register_operand" "%0,x")
738 (match_operand:V2SF 2 "register_operand" "x,x")))]
739 "TARGET_MMX_WITH_SSE"
740 "@
741 <logic>ps\t{%2, %0|%0, %2}
742 v<logic>ps\t{%2, %1, %0|%0, %1, %2}"
743 [(set_attr "isa" "noavx,avx")
744 (set_attr "type" "sselog")
745 (set_attr "prefix" "orig,vex")
746 (set_attr "mode" "V4SF")])
747
748 (define_expand "copysignv2sf3"
749 [(set (match_dup 4)
750 (and:V2SF
751 (not:V2SF (match_dup 3))
752 (match_operand:V2SF 1 "register_operand")))
753 (set (match_dup 5)
754 (and:V2SF (match_dup 3)
755 (match_operand:V2SF 2 "register_operand")))
756 (set (match_operand:V2SF 0 "register_operand")
757 (ior:V2SF (match_dup 4) (match_dup 5)))]
758 "TARGET_MMX_WITH_SSE"
759 {
760 operands[3] = ix86_build_signbit_mask (V2SFmode, true, false);
761
762 operands[4] = gen_reg_rtx (V2SFmode);
763 operands[5] = gen_reg_rtx (V2SFmode);
764 })
765
766 (define_expand "xorsignv2sf3"
767 [(set (match_dup 4)
768 (and:V2SF (match_dup 3)
769 (match_operand:V2SF 2 "register_operand")))
770 (set (match_operand:V2SF 0 "register_operand")
771 (xor:V2SF (match_dup 4)
772 (match_operand:V2SF 1 "register_operand")))]
773 "TARGET_MMX_WITH_SSE"
774 {
775 operands[3] = ix86_build_signbit_mask (V2SFmode, true, false);
776
777 operands[4] = gen_reg_rtx (V2SFmode);
778 })
779
780 (define_expand "signbitv2sf2"
781 [(set (match_operand:V2SI 0 "register_operand")
782 (lshiftrt:V2SI
783 (subreg:V2SI
784 (match_operand:V2SF 1 "register_operand") 0)
785 (match_dup 2)))]
786 "TARGET_MMX_WITH_SSE"
787 "operands[2] = GEN_INT (GET_MODE_UNIT_BITSIZE (V2SFmode)-1);")
788
789 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
790 ;;
791 ;; Parallel single-precision FMA multiply/accumulate instructions.
792 ;;
793 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
794
795 (define_insn "fmav2sf4"
796 [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
797 (fma:V2SF
798 (match_operand:V2SF 1 "register_operand" "%0,v,x")
799 (match_operand:V2SF 2 "register_operand" "v,v,x")
800 (match_operand:V2SF 3 "register_operand" "v,0,x")))]
801 "(TARGET_FMA || TARGET_FMA4) && TARGET_MMX_WITH_SSE"
802 "@
803 vfmadd132ps\t{%2, %3, %0|%0, %3, %2}
804 vfmadd231ps\t{%2, %1, %0|%0, %1, %2}
805 vfmaddps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
806 [(set_attr "isa" "fma,fma,fma4")
807 (set_attr "type" "ssemuladd")
808 (set_attr "mode" "V4SF")])
809
810 (define_insn "fmsv2sf4"
811 [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
812 (fma:V2SF
813 (match_operand:V2SF 1 "register_operand" "%0,v,x")
814 (match_operand:V2SF 2 "register_operand" "v,v,x")
815 (neg:V2SF
816 (match_operand:V2SF 3 "register_operand" "v,0,x"))))]
817 "(TARGET_FMA || TARGET_FMA4) && TARGET_MMX_WITH_SSE"
818 "@
819 vfmsub132ps\t{%2, %3, %0|%0, %3, %2}
820 vfmsub231ps\t{%2, %1, %0|%0, %1, %2}
821 vfmsubps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
822 [(set_attr "isa" "fma,fma,fma4")
823 (set_attr "type" "ssemuladd")
824 (set_attr "mode" "V4SF")])
825
826 (define_insn "fnmav2sf4"
827 [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
828 (fma:V2SF
829 (neg:V2SF
830 (match_operand:V2SF 1 "register_operand" "%0,v,x"))
831 (match_operand:V2SF 2 "register_operand" "v,v,x")
832 (match_operand:V2SF 3 "register_operand" "v,0,x")))]
833 "(TARGET_FMA || TARGET_FMA4) && TARGET_MMX_WITH_SSE"
834 "@
835 vfnmadd132ps\t{%2, %3, %0|%0, %3, %2}
836 vfnmadd231ps\t{%2, %1, %0|%0, %1, %2}
837 vfnmaddps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
838 [(set_attr "isa" "fma,fma,fma4")
839 (set_attr "type" "ssemuladd")
840 (set_attr "mode" "V4SF")])
841
842 (define_insn "fnmsv2sf4"
843 [(set (match_operand:V2SF 0 "register_operand" "=v,v,x")
844 (fma:V2SF
845 (neg:V2SF
846 (match_operand:V2SF 1 "register_operand" "%0,v,x"))
847 (match_operand:V2SF 2 "register_operand" "v,v,x")
848 (neg:V2SF
849 (match_operand:V2SF 3 "register_operand" "v,0,x"))))]
850 "(TARGET_FMA || TARGET_FMA4) && TARGET_MMX_WITH_SSE"
851 "@
852 vfnmsub132ps\t{%2, %3, %0|%0, %3, %2}
853 vfnmsub231ps\t{%2, %1, %0|%0, %1, %2}
854 vfnmsubps\t{%3, %2, %1, %0|%0, %1, %2, %3}"
855 [(set_attr "isa" "fma,fma,fma4")
856 (set_attr "type" "ssemuladd")
857 (set_attr "mode" "V4SF")])
858
859 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
860 ;;
861 ;; Parallel single-precision floating point conversion operations
862 ;;
863 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
864
865 (define_insn "mmx_fix_truncv2sfv2si2"
866 [(set (match_operand:V2SI 0 "register_operand" "=y,Yv")
867 (fix:V2SI (match_operand:V2SF 1 "register_mmxmem_operand" "ym,Yv")))]
868 "TARGET_3DNOW || TARGET_MMX_WITH_SSE"
869 "@
870 pf2id\t{%1, %0|%0, %1}
871 %vcvttps2dq\t{%1, %0|%0, %1}"
872 [(set_attr "isa" "*,sse2")
873 (set_attr "mmx_isa" "native,*")
874 (set_attr "type" "mmxcvt,ssecvt")
875 (set_attr "prefix_extra" "1,*")
876 (set_attr "prefix_rep" "*,1")
877 (set_attr "prefix_data16" "*,0")
878 (set_attr "prefix" "*,maybe_vex")
879 (set_attr "mode" "V2SF,TI")])
880
881 (define_expand "fix_truncv2sfv2si2"
882 [(set (match_operand:V2SI 0 "register_operand")
883 (fix:V2SI (match_operand:V2SF 1 "register_operand")))]
884 "TARGET_MMX_WITH_SSE")
885
886 (define_insn "fixuns_truncv2sfv2si2"
887 [(set (match_operand:V2SI 0 "register_operand" "=v")
888 (unsigned_fix:V2SI (match_operand:V2SF 1 "register_operand" "v")))]
889 "TARGET_MMX_WITH_SSE && TARGET_AVX512VL"
890 "vcvttps2udq\t{%1, %0|%0, %1}"
891 [(set_attr "type" "ssecvt")
892 (set_attr "prefix" "evex")
893 (set_attr "mode" "TI")])
894
895 (define_insn "mmx_floatv2siv2sf2"
896 [(set (match_operand:V2SF 0 "register_operand" "=y,Yv")
897 (float:V2SF (match_operand:V2SI 1 "register_mmxmem_operand" "ym,Yv")))]
898 "TARGET_3DNOW || TARGET_MMX_WITH_SSE"
899 "@
900 pi2fd\t{%1, %0|%0, %1}
901 %vcvtdq2ps\t{%1, %0|%0, %1}"
902 [(set_attr "isa" "*,sse2")
903 (set_attr "mmx_isa" "native,*")
904 (set_attr "type" "mmxcvt,ssecvt")
905 (set_attr "prefix_extra" "1")
906 (set_attr "prefix" "*,maybe_vex")
907 (set_attr "mode" "V2SF,V4SF")])
908
909 (define_expand "floatv2siv2sf2"
910 [(set (match_operand:V2SF 0 "register_operand")
911 (float:V2SF (match_operand:V2SI 1 "register_operand")))]
912 "TARGET_MMX_WITH_SSE")
913
914 (define_insn "floatunsv2siv2sf2"
915 [(set (match_operand:V2SF 0 "register_operand" "=v")
916 (unsigned_float:V2SF (match_operand:V2SI 1 "register_operand" "v")))]
917 "TARGET_MMX_WITH_SSE && TARGET_AVX512VL"
918 "vcvtudq2ps\t{%1, %0|%0, %1}"
919 [(set_attr "type" "ssecvt")
920 (set_attr "prefix" "evex")
921 (set_attr "mode" "V4SF")])
922
923 (define_insn "mmx_pf2iw"
924 [(set (match_operand:V2SI 0 "register_operand" "=y")
925 (sign_extend:V2SI
926 (ss_truncate:V2HI
927 (fix:V2SI
928 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
929 "TARGET_3DNOW_A"
930 "pf2iw\t{%1, %0|%0, %1}"
931 [(set_attr "type" "mmxcvt")
932 (set_attr "prefix_extra" "1")
933 (set_attr "mode" "V2SF")])
934
935 (define_insn "mmx_pi2fw"
936 [(set (match_operand:V2SF 0 "register_operand" "=y")
937 (float:V2SF
938 (sign_extend:V2SI
939 (truncate:V2HI
940 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))]
941 "TARGET_3DNOW_A"
942 "pi2fw\t{%1, %0|%0, %1}"
943 [(set_attr "type" "mmxcvt")
944 (set_attr "prefix_extra" "1")
945 (set_attr "mode" "V2SF")])
946
947 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
948 ;;
949 ;; Parallel single-precision floating point element swizzling
950 ;;
951 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
952
953 (define_insn "mmx_pswapdv2sf2"
954 [(set (match_operand:V2SF 0 "register_operand" "=y,x,Yv")
955 (vec_select:V2SF
956 (match_operand:V2SF 1 "register_mmxmem_operand" "ym,0,Yv")
957 (parallel [(const_int 1) (const_int 0)])))]
958 "TARGET_3DNOW_A || TARGET_MMX_WITH_SSE"
959 "@
960 pswapd\t{%1, %0|%0, %1}
961 shufps\t{$0xe1, %1, %0|%0, %1, 0xe1}
962 vshufps\t{$0xe1, %1, %1, %0|%0, %1, %1, 0xe1}"
963 [(set_attr "isa" "*,sse_noavx,avx")
964 (set_attr "mmx_isa" "native,*,*")
965 (set_attr "type" "mmxcvt,ssemov,ssemov")
966 (set_attr "prefix_extra" "1,*,*")
967 (set_attr "mode" "V2SF,V4SF,V4SF")])
968
969 (define_insn "*mmx_movshdup"
970 [(set (match_operand:V2SF 0 "register_operand" "=v,x")
971 (vec_select:V2SF
972 (match_operand:V2SF 1 "register_operand" "v,0")
973 (parallel [(const_int 1) (const_int 1)])))]
974 "TARGET_MMX_WITH_SSE"
975 "@
976 %vmovshdup\t{%1, %0|%0, %1}
977 shufps\t{$0xe5, %0, %0|%0, %0, 0xe5}"
978 [(set_attr "isa" "sse3,*")
979 (set_attr "type" "sse,sseshuf1")
980 (set_attr "length_immediate" "*,1")
981 (set_attr "prefix_rep" "1,*")
982 (set_attr "prefix" "maybe_vex,orig")
983 (set_attr "mode" "V4SF")])
984
985 (define_insn "*mmx_movsldup"
986 [(set (match_operand:V2SF 0 "register_operand" "=v,x")
987 (vec_select:V2SF
988 (match_operand:V2SF 1 "register_operand" "v,0")
989 (parallel [(const_int 0) (const_int 0)])))]
990 "TARGET_MMX_WITH_SSE"
991 "@
992 %vmovsldup\t{%1, %0|%0, %1}
993 shufps\t{$0xe0, %0, %0|%0, %0, 0xe0}"
994 [(set_attr "isa" "sse3,*")
995 (set_attr "type" "sse,sseshuf1")
996 (set_attr "length_immediate" "*,1")
997 (set_attr "prefix_rep" "1,*")
998 (set_attr "prefix" "maybe_vex,orig")
999 (set_attr "mode" "V4SF")])
1000
1001 (define_insn "*vec_dupv2sf"
1002 [(set (match_operand:V2SF 0 "register_operand" "=y,Yv,x")
1003 (vec_duplicate:V2SF
1004 (match_operand:SF 1 "register_operand" "0,Yv,0")))]
1005 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1006 "@
1007 punpckldq\t%0, %0
1008 %vmovsldup\t{%1, %0|%0, %1}
1009 shufps\t{$0xe0, %0, %0|%0, %0, 0xe0}"
1010 [(set_attr "isa" "*,sse3,sse_noavx")
1011 (set_attr "mmx_isa" "native,*,*")
1012 (set_attr "type" "mmxcvt,sse,sseshuf1")
1013 (set_attr "length_immediate" "*,*,1")
1014 (set_attr "prefix_rep" "*,1,*")
1015 (set_attr "prefix" "*,maybe_vex,orig")
1016 (set_attr "mode" "DI,V4SF,V4SF")])
1017
1018 (define_insn "*mmx_movss"
1019 [(set (match_operand:V2SF 0 "register_operand" "=x,v")
1020 (vec_merge:V2SF
1021 (match_operand:V2SF 2 "register_operand" " x,v")
1022 (match_operand:V2SF 1 "register_operand" " 0,v")
1023 (const_int 1)))]
1024 "TARGET_MMX_WITH_SSE"
1025 "@
1026 movss\t{%2, %0|%0, %2}
1027 vmovss\t{%2, %1, %0|%0, %1, %2}"
1028 [(set_attr "isa" "noavx,avx")
1029 (set_attr "type" "ssemov")
1030 (set_attr "prefix" "orig,maybe_evex")
1031 (set_attr "mode" "SF")])
1032
1033 (define_insn "*mmx_concatv2sf"
1034 [(set (match_operand:V2SF 0 "register_operand" "=y,y")
1035 (vec_concat:V2SF
1036 (match_operand:SF 1 "nonimmediate_operand" " 0,rm")
1037 (match_operand:SF 2 "nonimm_or_0_operand" "ym,C")))]
1038 "TARGET_MMX && !TARGET_SSE"
1039 "@
1040 punpckldq\t{%2, %0|%0, %2}
1041 movd\t{%1, %0|%0, %1}"
1042 [(set_attr "type" "mmxcvt,mmxmov")
1043 (set_attr "mode" "DI")])
1044
1045 (define_expand "vec_setv2sf"
1046 [(match_operand:V2SF 0 "register_operand")
1047 (match_operand:SF 1 "register_operand")
1048 (match_operand 2 "const_int_operand")]
1049 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1050 {
1051 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
1052 INTVAL (operands[2]));
1053 DONE;
1054 })
1055
1056 ;; Avoid combining registers from different units in a single alternative,
1057 ;; see comment above inline_secondary_memory_needed function in i386.c
1058 (define_insn_and_split "*vec_extractv2sf_0"
1059 [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r")
1060 (vec_select:SF
1061 (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m")
1062 (parallel [(const_int 0)])))]
1063 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1064 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1065 "#"
1066 "&& reload_completed"
1067 [(set (match_dup 0) (match_dup 1))]
1068 "operands[1] = gen_lowpart (SFmode, operands[1]);"
1069 [(set_attr "mmx_isa" "*,*,native,native,*,*")])
1070
1071 ;; Avoid combining registers from different units in a single alternative,
1072 ;; see comment above inline_secondary_memory_needed function in i386.c
1073 (define_insn "*vec_extractv2sf_1"
1074 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,x,y,x,f,r")
1075 (vec_select:SF
1076 (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,0,o,o,o,o")
1077 (parallel [(const_int 1)])))]
1078 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1079 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1080 "@
1081 punpckhdq\t%0, %0
1082 %vmovshdup\t{%1, %0|%0, %1}
1083 shufps\t{$0xe5, %0, %0|%0, %0, 0xe5}
1084 #
1085 #
1086 #
1087 #"
1088 [(set_attr "isa" "*,sse3,noavx,*,*,*,*")
1089 (set_attr "mmx_isa" "native,*,*,native,*,*,*")
1090 (set_attr "type" "mmxcvt,sse,sseshuf1,mmxmov,ssemov,fmov,imov")
1091 (set (attr "length_immediate")
1092 (if_then_else (eq_attr "alternative" "2")
1093 (const_string "1")
1094 (const_string "*")))
1095 (set (attr "prefix_rep")
1096 (if_then_else (eq_attr "alternative" "1")
1097 (const_string "1")
1098 (const_string "*")))
1099 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig")
1100 (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")])
1101
1102 (define_split
1103 [(set (match_operand:SF 0 "register_operand")
1104 (vec_select:SF
1105 (match_operand:V2SF 1 "memory_operand")
1106 (parallel [(const_int 1)])))]
1107 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed"
1108 [(set (match_dup 0) (match_dup 1))]
1109 "operands[1] = adjust_address (operands[1], SFmode, 4);")
1110
1111 (define_expand "vec_extractv2sfsf"
1112 [(match_operand:SF 0 "register_operand")
1113 (match_operand:V2SF 1 "register_operand")
1114 (match_operand 2 "const_int_operand")]
1115 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1116 {
1117 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
1118 operands[1], INTVAL (operands[2]));
1119 DONE;
1120 })
1121
1122 (define_expand "vec_initv2sfsf"
1123 [(match_operand:V2SF 0 "register_operand")
1124 (match_operand 1)]
1125 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
1126 {
1127 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
1128 operands[1]);
1129 DONE;
1130 })
1131
1132 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1133 ;;
1134 ;; Parallel integral arithmetic
1135 ;;
1136 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1137
1138 (define_expand "mmx_<plusminus_insn><mode>3"
1139 [(set (match_operand:MMXMODEI8 0 "register_operand")
1140 (plusminus:MMXMODEI8
1141 (match_operand:MMXMODEI8 1 "register_mmxmem_operand")
1142 (match_operand:MMXMODEI8 2 "register_mmxmem_operand")))]
1143 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1144 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1145
1146 (define_expand "<plusminus_insn><mode>3"
1147 [(set (match_operand:MMXMODEI 0 "register_operand")
1148 (plusminus:MMXMODEI
1149 (match_operand:MMXMODEI 1 "register_operand")
1150 (match_operand:MMXMODEI 2 "register_operand")))]
1151 "TARGET_MMX_WITH_SSE"
1152 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1153
1154 (define_insn "*mmx_<plusminus_insn><mode>3"
1155 [(set (match_operand:MMXMODEI8 0 "register_operand" "=y,x,Yv")
1156 (plusminus:MMXMODEI8
1157 (match_operand:MMXMODEI8 1 "register_mmxmem_operand" "<comm>0,0,Yv")
1158 (match_operand:MMXMODEI8 2 "register_mmxmem_operand" "ym,x,Yv")))]
1159 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1160 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1161 "@
1162 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1163 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1164 vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1165 [(set_attr "isa" "*,sse2_noavx,avx")
1166 (set_attr "mmx_isa" "native,*,*")
1167 (set_attr "type" "mmxadd,sseadd,sseadd")
1168 (set_attr "mode" "DI,TI,TI")])
1169
1170 (define_expand "mmx_<plusminus_insn><mode>3"
1171 [(set (match_operand:MMXMODE12 0 "register_operand")
1172 (sat_plusminus:MMXMODE12
1173 (match_operand:MMXMODE12 1 "register_mmxmem_operand")
1174 (match_operand:MMXMODE12 2 "register_mmxmem_operand")))]
1175 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1176 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1177
1178 (define_insn "*mmx_<plusminus_insn><mode>3"
1179 [(set (match_operand:MMXMODE12 0 "register_operand" "=y,x,Yv")
1180 (sat_plusminus:MMXMODE12
1181 (match_operand:MMXMODE12 1 "register_mmxmem_operand" "<comm>0,0,Yv")
1182 (match_operand:MMXMODE12 2 "register_mmxmem_operand" "ym,x,Yv")))]
1183 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1184 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1185 "@
1186 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1187 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}
1188 vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1189 [(set_attr "isa" "*,sse2_noavx,avx")
1190 (set_attr "mmx_isa" "native,*,*")
1191 (set_attr "type" "mmxadd,sseadd,sseadd")
1192 (set_attr "mode" "DI,TI,TI")])
1193
1194 (define_expand "mmx_mulv4hi3"
1195 [(set (match_operand:V4HI 0 "register_operand")
1196 (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand")
1197 (match_operand:V4HI 2 "register_mmxmem_operand")))]
1198 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1199 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1200
1201 (define_expand "mulv4hi3"
1202 [(set (match_operand:V4HI 0 "register_operand")
1203 (mult:V4HI (match_operand:V4HI 1 "register_operand")
1204 (match_operand:V4HI 2 "register_operand")))]
1205 "TARGET_MMX_WITH_SSE"
1206 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1207
1208 (define_insn "*mmx_mulv4hi3"
1209 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1210 (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
1211 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1212 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1213 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1214 "@
1215 pmullw\t{%2, %0|%0, %2}
1216 pmullw\t{%2, %0|%0, %2}
1217 vpmullw\t{%2, %1, %0|%0, %1, %2}"
1218 [(set_attr "isa" "*,sse2_noavx,avx")
1219 (set_attr "mmx_isa" "native,*,*")
1220 (set_attr "type" "mmxmul,ssemul,ssemul")
1221 (set_attr "mode" "DI,TI,TI")])
1222
1223 (define_expand "mmx_smulv4hi3_highpart"
1224 [(set (match_operand:V4HI 0 "register_operand")
1225 (truncate:V4HI
1226 (lshiftrt:V4SI
1227 (mult:V4SI
1228 (sign_extend:V4SI
1229 (match_operand:V4HI 1 "register_mmxmem_operand"))
1230 (sign_extend:V4SI
1231 (match_operand:V4HI 2 "register_mmxmem_operand")))
1232 (const_int 16))))]
1233 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1234 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1235
1236 (define_insn "*mmx_smulv4hi3_highpart"
1237 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1238 (truncate:V4HI
1239 (lshiftrt:V4SI
1240 (mult:V4SI
1241 (sign_extend:V4SI
1242 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
1243 (sign_extend:V4SI
1244 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
1245 (const_int 16))))]
1246 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1247 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1248 "@
1249 pmulhw\t{%2, %0|%0, %2}
1250 pmulhw\t{%2, %0|%0, %2}
1251 vpmulhw\t{%2, %1, %0|%0, %1, %2}"
1252 [(set_attr "isa" "*,sse2_noavx,avx")
1253 (set_attr "mmx_isa" "native,*,*")
1254 (set_attr "type" "mmxmul,ssemul,ssemul")
1255 (set_attr "mode" "DI,TI,TI")])
1256
1257 (define_expand "mmx_umulv4hi3_highpart"
1258 [(set (match_operand:V4HI 0 "register_operand")
1259 (truncate:V4HI
1260 (lshiftrt:V4SI
1261 (mult:V4SI
1262 (zero_extend:V4SI
1263 (match_operand:V4HI 1 "register_mmxmem_operand"))
1264 (zero_extend:V4SI
1265 (match_operand:V4HI 2 "register_mmxmem_operand")))
1266 (const_int 16))))]
1267 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1268 && (TARGET_SSE || TARGET_3DNOW_A)"
1269 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1270
1271 (define_insn "*mmx_umulv4hi3_highpart"
1272 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1273 (truncate:V4HI
1274 (lshiftrt:V4SI
1275 (mult:V4SI
1276 (zero_extend:V4SI
1277 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
1278 (zero_extend:V4SI
1279 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
1280 (const_int 16))))]
1281 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1282 && (TARGET_SSE || TARGET_3DNOW_A)
1283 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1284 "@
1285 pmulhuw\t{%2, %0|%0, %2}
1286 pmulhuw\t{%2, %0|%0, %2}
1287 vpmulhuw\t{%2, %1, %0|%0, %1, %2}"
1288 [(set_attr "isa" "*,sse2_noavx,avx")
1289 (set_attr "mmx_isa" "native,*,*")
1290 (set_attr "type" "mmxmul,ssemul,ssemul")
1291 (set_attr "mode" "DI,TI,TI")])
1292
1293 (define_expand "mmx_pmaddwd"
1294 [(set (match_operand:V2SI 0 "register_operand")
1295 (plus:V2SI
1296 (mult:V2SI
1297 (sign_extend:V2SI
1298 (vec_select:V2HI
1299 (match_operand:V4HI 1 "register_mmxmem_operand")
1300 (parallel [(const_int 0) (const_int 2)])))
1301 (sign_extend:V2SI
1302 (vec_select:V2HI
1303 (match_operand:V4HI 2 "register_mmxmem_operand")
1304 (parallel [(const_int 0) (const_int 2)]))))
1305 (mult:V2SI
1306 (sign_extend:V2SI
1307 (vec_select:V2HI (match_dup 1)
1308 (parallel [(const_int 1) (const_int 3)])))
1309 (sign_extend:V2SI
1310 (vec_select:V2HI (match_dup 2)
1311 (parallel [(const_int 1) (const_int 3)]))))))]
1312 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1313 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1314
1315 (define_insn "*mmx_pmaddwd"
1316 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1317 (plus:V2SI
1318 (mult:V2SI
1319 (sign_extend:V2SI
1320 (vec_select:V2HI
1321 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
1322 (parallel [(const_int 0) (const_int 2)])))
1323 (sign_extend:V2SI
1324 (vec_select:V2HI
1325 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")
1326 (parallel [(const_int 0) (const_int 2)]))))
1327 (mult:V2SI
1328 (sign_extend:V2SI
1329 (vec_select:V2HI (match_dup 1)
1330 (parallel [(const_int 1) (const_int 3)])))
1331 (sign_extend:V2SI
1332 (vec_select:V2HI (match_dup 2)
1333 (parallel [(const_int 1) (const_int 3)]))))))]
1334 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1335 && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1336 "@
1337 pmaddwd\t{%2, %0|%0, %2}
1338 pmaddwd\t{%2, %0|%0, %2}
1339 vpmaddwd\t{%2, %1, %0|%0, %1, %2}"
1340 [(set_attr "isa" "*,sse2_noavx,avx")
1341 (set_attr "mmx_isa" "native,*,*")
1342 (set_attr "type" "mmxmul,sseiadd,sseiadd")
1343 (set_attr "mode" "DI,TI,TI")])
1344
1345 (define_expand "mmx_pmulhrwv4hi3"
1346 [(set (match_operand:V4HI 0 "register_operand")
1347 (truncate:V4HI
1348 (lshiftrt:V4SI
1349 (plus:V4SI
1350 (mult:V4SI
1351 (sign_extend:V4SI
1352 (match_operand:V4HI 1 "nonimmediate_operand"))
1353 (sign_extend:V4SI
1354 (match_operand:V4HI 2 "nonimmediate_operand")))
1355 (const_vector:V4SI [(const_int 32768) (const_int 32768)
1356 (const_int 32768) (const_int 32768)]))
1357 (const_int 16))))]
1358 "TARGET_3DNOW"
1359 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);")
1360
1361 (define_insn "*mmx_pmulhrwv4hi3"
1362 [(set (match_operand:V4HI 0 "register_operand" "=y")
1363 (truncate:V4HI
1364 (lshiftrt:V4SI
1365 (plus:V4SI
1366 (mult:V4SI
1367 (sign_extend:V4SI
1368 (match_operand:V4HI 1 "nonimmediate_operand" "%0"))
1369 (sign_extend:V4SI
1370 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
1371 (const_vector:V4SI [(const_int 32768) (const_int 32768)
1372 (const_int 32768) (const_int 32768)]))
1373 (const_int 16))))]
1374 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
1375 "pmulhrw\t{%2, %0|%0, %2}"
1376 [(set_attr "type" "mmxmul")
1377 (set_attr "prefix_extra" "1")
1378 (set_attr "mode" "DI")])
1379
1380 (define_expand "sse2_umulv1siv1di3"
1381 [(set (match_operand:V1DI 0 "register_operand")
1382 (mult:V1DI
1383 (zero_extend:V1DI
1384 (vec_select:V1SI
1385 (match_operand:V2SI 1 "register_mmxmem_operand")
1386 (parallel [(const_int 0)])))
1387 (zero_extend:V1DI
1388 (vec_select:V1SI
1389 (match_operand:V2SI 2 "register_mmxmem_operand")
1390 (parallel [(const_int 0)])))))]
1391 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE2"
1392 "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);")
1393
1394 (define_insn "*sse2_umulv1siv1di3"
1395 [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv")
1396 (mult:V1DI
1397 (zero_extend:V1DI
1398 (vec_select:V1SI
1399 (match_operand:V2SI 1 "register_mmxmem_operand" "%0,0,Yv")
1400 (parallel [(const_int 0)])))
1401 (zero_extend:V1DI
1402 (vec_select:V1SI
1403 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv")
1404 (parallel [(const_int 0)])))))]
1405 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1406 && TARGET_SSE2
1407 && ix86_binary_operator_ok (MULT, V2SImode, operands)"
1408 "@
1409 pmuludq\t{%2, %0|%0, %2}
1410 pmuludq\t{%2, %0|%0, %2}
1411 vpmuludq\t{%2, %1, %0|%0, %1, %2}"
1412 [(set_attr "isa" "*,sse2_noavx,avx")
1413 (set_attr "mmx_isa" "native,*,*")
1414 (set_attr "type" "mmxmul,ssemul,ssemul")
1415 (set_attr "mode" "DI,TI,TI")])
1416
1417 (define_expand "mmx_<code>v4hi3"
1418 [(set (match_operand:V4HI 0 "register_operand")
1419 (smaxmin:V4HI
1420 (match_operand:V4HI 1 "register_mmxmem_operand")
1421 (match_operand:V4HI 2 "register_mmxmem_operand")))]
1422 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1423 && (TARGET_SSE || TARGET_3DNOW_A)"
1424 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
1425
1426 (define_expand "<code>v4hi3"
1427 [(set (match_operand:V4HI 0 "register_operand")
1428 (smaxmin:V4HI
1429 (match_operand:V4HI 1 "register_operand")
1430 (match_operand:V4HI 2 "register_operand")))]
1431 "TARGET_MMX_WITH_SSE"
1432 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);")
1433
1434 (define_insn "*mmx_<code>v4hi3"
1435 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1436 (smaxmin:V4HI
1437 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")
1438 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1439 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1440 && (TARGET_SSE || TARGET_3DNOW_A)
1441 && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
1442 "@
1443 p<maxmin_int>w\t{%2, %0|%0, %2}
1444 p<maxmin_int>w\t{%2, %0|%0, %2}
1445 vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}"
1446 [(set_attr "isa" "*,sse2_noavx,avx")
1447 (set_attr "mmx_isa" "native,*,*")
1448 (set_attr "type" "mmxadd,sseiadd,sseiadd")
1449 (set_attr "mode" "DI,TI,TI")])
1450
1451 (define_expand "mmx_<code>v8qi3"
1452 [(set (match_operand:V8QI 0 "register_operand")
1453 (umaxmin:V8QI
1454 (match_operand:V8QI 1 "register_mmxmem_operand")
1455 (match_operand:V8QI 2 "register_mmxmem_operand")))]
1456 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1457 && (TARGET_SSE || TARGET_3DNOW_A)"
1458 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1459
1460 (define_expand "<code>v8qi3"
1461 [(set (match_operand:V8QI 0 "register_operand")
1462 (umaxmin:V8QI
1463 (match_operand:V8QI 1 "register_operand")
1464 (match_operand:V8QI 2 "register_operand")))]
1465 "TARGET_MMX_WITH_SSE"
1466 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);")
1467
1468 (define_insn "*mmx_<code>v8qi3"
1469 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1470 (umaxmin:V8QI
1471 (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yv")
1472 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1473 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1474 && (TARGET_SSE || TARGET_3DNOW_A)
1475 && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
1476 "@
1477 p<maxmin_int>b\t{%2, %0|%0, %2}
1478 p<maxmin_int>b\t{%2, %0|%0, %2}
1479 vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}"
1480 [(set_attr "isa" "*,sse2_noavx,avx")
1481 (set_attr "mmx_isa" "native,*,*")
1482 (set_attr "type" "mmxadd,sseiadd,sseiadd")
1483 (set_attr "mode" "DI,TI,TI")])
1484
1485 (define_insn "mmx_ashr<mode>3"
1486 [(set (match_operand:MMXMODE24 0 "register_operand" "=y,x,Yv")
1487 (ashiftrt:MMXMODE24
1488 (match_operand:MMXMODE24 1 "register_operand" "0,0,Yv")
1489 (match_operand:DI 2 "nonmemory_operand" "yN,xN,YvN")))]
1490 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1491 "@
1492 psra<mmxvecsize>\t{%2, %0|%0, %2}
1493 psra<mmxvecsize>\t{%2, %0|%0, %2}
1494 vpsra<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1495 [(set_attr "isa" "*,sse2_noavx,avx")
1496 (set_attr "mmx_isa" "native,*,*")
1497 (set_attr "type" "mmxshft,sseishft,sseishft")
1498 (set (attr "length_immediate")
1499 (if_then_else (match_operand 2 "const_int_operand")
1500 (const_string "1")
1501 (const_string "0")))
1502 (set_attr "mode" "DI,TI,TI")])
1503
1504 (define_expand "ashr<mode>3"
1505 [(set (match_operand:MMXMODE24 0 "register_operand")
1506 (ashiftrt:MMXMODE24
1507 (match_operand:MMXMODE24 1 "register_operand")
1508 (match_operand:DI 2 "nonmemory_operand")))]
1509 "TARGET_MMX_WITH_SSE")
1510
1511 (define_insn "mmx_<shift_insn><mode>3"
1512 [(set (match_operand:MMXMODE248 0 "register_operand" "=y,x,Yv")
1513 (any_lshift:MMXMODE248
1514 (match_operand:MMXMODE248 1 "register_operand" "0,0,Yv")
1515 (match_operand:DI 2 "nonmemory_operand" "yN,xN,YvN")))]
1516 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1517 "@
1518 p<vshift><mmxvecsize>\t{%2, %0|%0, %2}
1519 p<vshift><mmxvecsize>\t{%2, %0|%0, %2}
1520 vp<vshift><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1521 [(set_attr "isa" "*,sse2_noavx,avx")
1522 (set_attr "mmx_isa" "native,*,*")
1523 (set_attr "type" "mmxshft,sseishft,sseishft")
1524 (set (attr "length_immediate")
1525 (if_then_else (match_operand 2 "const_int_operand")
1526 (const_string "1")
1527 (const_string "0")))
1528 (set_attr "mode" "DI,TI,TI")])
1529
1530 (define_expand "<shift_insn><mode>3"
1531 [(set (match_operand:MMXMODE248 0 "register_operand")
1532 (any_lshift:MMXMODE248
1533 (match_operand:MMXMODE248 1 "register_operand")
1534 (match_operand:DI 2 "nonmemory_operand")))]
1535 "TARGET_MMX_WITH_SSE")
1536
1537 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1538 ;;
1539 ;; Parallel integral comparisons
1540 ;;
1541 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1542
1543 (define_expand "mmx_eq<mode>3"
1544 [(set (match_operand:MMXMODEI 0 "register_operand")
1545 (eq:MMXMODEI
1546 (match_operand:MMXMODEI 1 "register_mmxmem_operand")
1547 (match_operand:MMXMODEI 2 "register_mmxmem_operand")))]
1548 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1549 "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);")
1550
1551 (define_insn "*mmx_eq<mode>3"
1552 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1553 (eq:MMXMODEI
1554 (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,Yv")
1555 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1556 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1557 && ix86_binary_operator_ok (EQ, <MODE>mode, operands)"
1558 "@
1559 pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
1560 pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}
1561 vpcmpeq<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1562 [(set_attr "isa" "*,sse2_noavx,avx")
1563 (set_attr "mmx_isa" "native,*,*")
1564 (set_attr "type" "mmxcmp,ssecmp,ssecmp")
1565 (set_attr "mode" "DI,TI,TI")])
1566
1567 (define_insn "mmx_gt<mode>3"
1568 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1569 (gt:MMXMODEI
1570 (match_operand:MMXMODEI 1 "register_operand" "0,0,Yv")
1571 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1572 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1573 "@
1574 pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
1575 pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}
1576 vpcmpgt<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}"
1577 [(set_attr "isa" "*,sse2_noavx,avx")
1578 (set_attr "mmx_isa" "native,*,*")
1579 (set_attr "type" "mmxcmp,ssecmp,ssecmp")
1580 (set_attr "mode" "DI,TI,TI")])
1581
1582 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1583 ;;
1584 ;; Parallel integral logical operations
1585 ;;
1586 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1587
1588 (define_expand "one_cmpl<mode>2"
1589 [(set (match_operand:MMXMODEI 0 "register_operand")
1590 (xor:MMXMODEI
1591 (match_operand:MMXMODEI 1 "register_operand")
1592 (match_dup 2)))]
1593 "TARGET_MMX_WITH_SSE"
1594 "operands[2] = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));")
1595
1596 (define_insn "mmx_andnot<mode>3"
1597 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1598 (and:MMXMODEI
1599 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0,0,Yv"))
1600 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1601 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1602 "@
1603 pandn\t{%2, %0|%0, %2}
1604 pandn\t{%2, %0|%0, %2}
1605 vpandn\t{%2, %1, %0|%0, %1, %2}"
1606 [(set_attr "isa" "*,sse2_noavx,avx")
1607 (set_attr "mmx_isa" "native,*,*")
1608 (set_attr "type" "mmxadd,sselog,sselog")
1609 (set_attr "mode" "DI,TI,TI")])
1610
1611 (define_expand "mmx_<code><mode>3"
1612 [(set (match_operand:MMXMODEI 0 "register_operand")
1613 (any_logic:MMXMODEI
1614 (match_operand:MMXMODEI 1 "register_mmxmem_operand")
1615 (match_operand:MMXMODEI 2 "register_mmxmem_operand")))]
1616 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1617 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1618
1619 (define_expand "<code><mode>3"
1620 [(set (match_operand:MMXMODEI 0 "register_operand")
1621 (any_logic:MMXMODEI
1622 (match_operand:MMXMODEI 1 "register_operand")
1623 (match_operand:MMXMODEI 2 "register_operand")))]
1624 "TARGET_MMX_WITH_SSE"
1625 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
1626
1627 (define_insn "*mmx_<code><mode>3"
1628 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv")
1629 (any_logic:MMXMODEI
1630 (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,Yv")
1631 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))]
1632 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1633 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
1634 "@
1635 p<logic>\t{%2, %0|%0, %2}
1636 p<logic>\t{%2, %0|%0, %2}
1637 vp<logic>\t{%2, %1, %0|%0, %1, %2}"
1638 [(set_attr "isa" "*,sse2_noavx,avx")
1639 (set_attr "mmx_isa" "native,*,*")
1640 (set_attr "type" "mmxadd,sselog,sselog")
1641 (set_attr "mode" "DI,TI,TI")])
1642
1643 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1644 ;;
1645 ;; Parallel integral element swizzling
1646 ;;
1647 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1648
1649 ;; Used in signed and unsigned truncations with saturation.
1650 (define_code_iterator any_s_truncate [ss_truncate us_truncate])
1651 ;; Instruction suffix for truncations with saturation.
1652 (define_code_attr s_trunsuffix [(ss_truncate "s") (us_truncate "u")])
1653
1654 (define_insn_and_split "mmx_pack<s_trunsuffix>swb"
1655 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1656 (vec_concat:V8QI
1657 (any_s_truncate:V4QI
1658 (match_operand:V4HI 1 "register_operand" "0,0,Yv"))
1659 (any_s_truncate:V4QI
1660 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))))]
1661 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1662 "@
1663 pack<s_trunsuffix>swb\t{%2, %0|%0, %2}
1664 #
1665 #"
1666 "TARGET_SSE2 && reload_completed
1667 && SSE_REGNO_P (REGNO (operands[0]))"
1668 [(const_int 0)]
1669 "ix86_split_mmx_pack (operands, <any_s_truncate:CODE>); DONE;"
1670 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1671 (set_attr "type" "mmxshft,sselog,sselog")
1672 (set_attr "mode" "DI,TI,TI")])
1673
1674 (define_insn_and_split "mmx_packssdw"
1675 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1676 (vec_concat:V4HI
1677 (ss_truncate:V2HI
1678 (match_operand:V2SI 1 "register_operand" "0,0,Yv"))
1679 (ss_truncate:V2HI
1680 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))))]
1681 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1682 "@
1683 packssdw\t{%2, %0|%0, %2}
1684 #
1685 #"
1686 "TARGET_SSE2 && reload_completed
1687 && SSE_REGNO_P (REGNO (operands[0]))"
1688 [(const_int 0)]
1689 "ix86_split_mmx_pack (operands, SS_TRUNCATE); DONE;"
1690 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1691 (set_attr "type" "mmxshft,sselog,sselog")
1692 (set_attr "mode" "DI,TI,TI")])
1693
1694 (define_insn_and_split "mmx_punpckhbw"
1695 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1696 (vec_select:V8QI
1697 (vec_concat:V16QI
1698 (match_operand:V8QI 1 "register_operand" "0,0,Yv")
1699 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))
1700 (parallel [(const_int 4) (const_int 12)
1701 (const_int 5) (const_int 13)
1702 (const_int 6) (const_int 14)
1703 (const_int 7) (const_int 15)])))]
1704 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1705 "@
1706 punpckhbw\t{%2, %0|%0, %2}
1707 #
1708 #"
1709 "TARGET_SSE2 && reload_completed
1710 && SSE_REGNO_P (REGNO (operands[0]))"
1711 [(const_int 0)]
1712 "ix86_split_mmx_punpck (operands, true); DONE;"
1713 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1714 (set_attr "type" "mmxcvt,sselog,sselog")
1715 (set_attr "mode" "DI,TI,TI")])
1716
1717 (define_insn_and_split "mmx_punpcklbw"
1718 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
1719 (vec_select:V8QI
1720 (vec_concat:V16QI
1721 (match_operand:V8QI 1 "register_operand" "0,0,Yv")
1722 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))
1723 (parallel [(const_int 0) (const_int 8)
1724 (const_int 1) (const_int 9)
1725 (const_int 2) (const_int 10)
1726 (const_int 3) (const_int 11)])))]
1727 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1728 "@
1729 punpcklbw\t{%2, %0|%0, %k2}
1730 #
1731 #"
1732 "TARGET_SSE2 && reload_completed
1733 && SSE_REGNO_P (REGNO (operands[0]))"
1734 [(const_int 0)]
1735 "ix86_split_mmx_punpck (operands, false); DONE;"
1736 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1737 (set_attr "type" "mmxcvt,sselog,sselog")
1738 (set_attr "mode" "DI,TI,TI")])
1739
1740 (define_insn_and_split "mmx_punpckhwd"
1741 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1742 (vec_select:V4HI
1743 (vec_concat:V8HI
1744 (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1745 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))
1746 (parallel [(const_int 2) (const_int 6)
1747 (const_int 3) (const_int 7)])))]
1748 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1749 "@
1750 punpckhwd\t{%2, %0|%0, %2}
1751 #
1752 #"
1753 "TARGET_SSE2 && reload_completed
1754 && SSE_REGNO_P (REGNO (operands[0]))"
1755 [(const_int 0)]
1756 "ix86_split_mmx_punpck (operands, true); DONE;"
1757 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1758 (set_attr "type" "mmxcvt,sselog,sselog")
1759 (set_attr "mode" "DI,TI,TI")])
1760
1761 (define_insn_and_split "mmx_punpcklwd"
1762 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1763 (vec_select:V4HI
1764 (vec_concat:V8HI
1765 (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1766 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))
1767 (parallel [(const_int 0) (const_int 4)
1768 (const_int 1) (const_int 5)])))]
1769 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1770 "@
1771 punpcklwd\t{%2, %0|%0, %k2}
1772 #
1773 #"
1774 "TARGET_SSE2 && reload_completed
1775 && SSE_REGNO_P (REGNO (operands[0]))"
1776 [(const_int 0)]
1777 "ix86_split_mmx_punpck (operands, false); DONE;"
1778 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1779 (set_attr "type" "mmxcvt,sselog,sselog")
1780 (set_attr "mode" "DI,TI,TI")])
1781
1782 (define_insn_and_split "mmx_punpckhdq"
1783 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1784 (vec_select:V2SI
1785 (vec_concat:V4SI
1786 (match_operand:V2SI 1 "register_operand" "0,0,Yv")
1787 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
1788 (parallel [(const_int 1)
1789 (const_int 3)])))]
1790 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1791 "@
1792 punpckhdq\t{%2, %0|%0, %2}
1793 #
1794 #"
1795 "TARGET_SSE2 && reload_completed
1796 && SSE_REGNO_P (REGNO (operands[0]))"
1797 [(const_int 0)]
1798 "ix86_split_mmx_punpck (operands, true); DONE;"
1799 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1800 (set_attr "type" "mmxcvt,sselog,sselog")
1801 (set_attr "mode" "DI,TI,TI")])
1802
1803 (define_insn_and_split "mmx_punpckldq"
1804 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv")
1805 (vec_select:V2SI
1806 (vec_concat:V4SI
1807 (match_operand:V2SI 1 "register_operand" "0,0,Yv")
1808 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))
1809 (parallel [(const_int 0)
1810 (const_int 2)])))]
1811 "TARGET_MMX || TARGET_MMX_WITH_SSE"
1812 "@
1813 punpckldq\t{%2, %0|%0, %k2}
1814 #
1815 #"
1816 "TARGET_SSE2 && reload_completed
1817 && SSE_REGNO_P (REGNO (operands[0]))"
1818 [(const_int 0)]
1819 "ix86_split_mmx_punpck (operands, false); DONE;"
1820 [(set_attr "mmx_isa" "native,sse_noavx,avx")
1821 (set_attr "type" "mmxcvt,sselog,sselog")
1822 (set_attr "mode" "DI,TI,TI")])
1823
1824 (define_insn "*mmx_pinsrd"
1825 [(set (match_operand:V2SI 0 "register_operand" "=x,Yv")
1826 (vec_merge:V2SI
1827 (vec_duplicate:V2SI
1828 (match_operand:SI 2 "nonimmediate_operand" "rm,rm"))
1829 (match_operand:V2SI 1 "register_operand" "0,Yv")
1830 (match_operand:SI 3 "const_int_operand")))]
1831 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1
1832 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1833 < GET_MODE_NUNITS (V2SImode))"
1834 {
1835 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1836 switch (which_alternative)
1837 {
1838 case 1:
1839 return "vpinsrd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1840 case 0:
1841 return "pinsrd\t{%3, %2, %0|%0, %2, %3}";
1842 default:
1843 gcc_unreachable ();
1844 }
1845 }
1846 [(set_attr "isa" "noavx,avx")
1847 (set_attr "prefix_data16" "1")
1848 (set_attr "prefix_extra" "1")
1849 (set_attr "type" "sselog")
1850 (set_attr "length_immediate" "1")
1851 (set_attr "prefix" "orig,vex")
1852 (set_attr "mode" "TI")])
1853
1854 (define_expand "mmx_pinsrw"
1855 [(set (match_operand:V4HI 0 "register_operand")
1856 (vec_merge:V4HI
1857 (vec_duplicate:V4HI
1858 (match_operand:SI 2 "nonimmediate_operand"))
1859 (match_operand:V4HI 1 "register_operand")
1860 (match_operand:SI 3 "const_0_to_3_operand")))]
1861 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1862 && (TARGET_SSE || TARGET_3DNOW_A)"
1863 {
1864 operands[2] = gen_lowpart (HImode, operands[2]);
1865 operands[3] = GEN_INT (1 << INTVAL (operands[3]));
1866 })
1867
1868 (define_insn "*mmx_pinsrw"
1869 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
1870 (vec_merge:V4HI
1871 (vec_duplicate:V4HI
1872 (match_operand:HI 2 "nonimmediate_operand" "rm,rm,rm"))
1873 (match_operand:V4HI 1 "register_operand" "0,0,Yv")
1874 (match_operand:SI 3 "const_int_operand")))]
1875 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1876 && (TARGET_SSE || TARGET_3DNOW_A)
1877 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1878 < GET_MODE_NUNITS (V4HImode))"
1879 {
1880 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1881 switch (which_alternative)
1882 {
1883 case 2:
1884 if (MEM_P (operands[2]))
1885 return "vpinsrw\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1886 else
1887 return "vpinsrw\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
1888 case 1:
1889 case 0:
1890 if (MEM_P (operands[2]))
1891 return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
1892 else
1893 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
1894 default:
1895 gcc_unreachable ();
1896 }
1897 }
1898 [(set_attr "isa" "*,sse2_noavx,avx")
1899 (set_attr "mmx_isa" "native,*,*")
1900 (set_attr "type" "mmxcvt,sselog,sselog")
1901 (set_attr "length_immediate" "1")
1902 (set_attr "mode" "DI,TI,TI")])
1903
1904 (define_insn "*mmx_pinsrb"
1905 [(set (match_operand:V8QI 0 "register_operand" "=x,Yv")
1906 (vec_merge:V8QI
1907 (vec_duplicate:V8QI
1908 (match_operand:QI 2 "nonimmediate_operand" "rm,rm"))
1909 (match_operand:V8QI 1 "register_operand" "0,Yv")
1910 (match_operand:SI 3 "const_int_operand")))]
1911 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1
1912 && ((unsigned) exact_log2 (INTVAL (operands[3]))
1913 < GET_MODE_NUNITS (V8QImode))"
1914 {
1915 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
1916 switch (which_alternative)
1917 {
1918 case 1:
1919 if (MEM_P (operands[2]))
1920 return "vpinsrb\t{%3, %2, %1, %0|%0, %1, %2, %3}";
1921 else
1922 return "vpinsrb\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
1923 case 0:
1924 if (MEM_P (operands[2]))
1925 return "pinsrb\t{%3, %2, %0|%0, %2, %3}";
1926 else
1927 return "pinsrb\t{%3, %k2, %0|%0, %k2, %3}";
1928 default:
1929 gcc_unreachable ();
1930 }
1931 }
1932 [(set_attr "isa" "noavx,avx")
1933 (set_attr "type" "sselog")
1934 (set_attr "prefix_data16" "1")
1935 (set_attr "prefix_extra" "1")
1936 (set_attr "length_immediate" "1")
1937 (set_attr "prefix" "orig,vex")
1938 (set_attr "mode" "TI")])
1939
1940 (define_insn "*mmx_pextrw"
1941 [(set (match_operand:HI 0 "register_sse4nonimm_operand" "=r,r,m")
1942 (vec_select:HI
1943 (match_operand:V4HI 1 "register_operand" "y,Yv,Yv")
1944 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n,n")])))]
1945 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1946 && (TARGET_SSE || TARGET_3DNOW_A)"
1947 "@
1948 pextrw\t{%2, %1, %k0|%k0, %1, %2}
1949 %vpextrw\t{%2, %1, %k0|%k0, %1, %2}
1950 %vpextrw\t{%2, %1, %0|%0, %1, %2}"
1951 [(set_attr "isa" "*,sse2,sse4")
1952 (set_attr "mmx_isa" "native,*,*")
1953 (set_attr "type" "mmxcvt,sselog1,sselog1")
1954 (set_attr "length_immediate" "1")
1955 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
1956 (set_attr "mode" "DI,TI,TI")])
1957
1958 (define_insn "*mmx_pextrw_zext"
1959 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
1960 (zero_extend:SWI48
1961 (vec_select:HI
1962 (match_operand:V4HI 1 "register_operand" "y,Yv")
1963 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n")]))))]
1964 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
1965 && (TARGET_SSE || TARGET_3DNOW_A)"
1966 "@
1967 pextrw\t{%2, %1, %k0|%k0, %1, %2}
1968 %vpextrw\t{%2, %1, %k0|%k0, %1, %2}"
1969 [(set_attr "isa" "*,sse2")
1970 (set_attr "mmx_isa" "native,*")
1971 (set_attr "type" "mmxcvt,sselog1")
1972 (set_attr "length_immediate" "1")
1973 (set_attr "prefix" "orig,maybe_vex")
1974 (set_attr "mode" "DI,TI")])
1975
1976 (define_insn "*mmx_pextrb"
1977 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,m")
1978 (vec_select:QI
1979 (match_operand:V8QI 1 "register_operand" "Yv,Yv")
1980 (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n,n")])))]
1981 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1"
1982 "@
1983 %vpextrb\t{%2, %1, %k0|%k0, %1, %2}
1984 %vpextrb\t{%2, %1, %0|%0, %1, %2}"
1985 [(set_attr "type" "sselog1")
1986 (set_attr "prefix_data16" "1")
1987 (set_attr "prefix_extra" "1")
1988 (set_attr "length_immediate" "1")
1989 (set_attr "prefix" "maybe_vex")
1990 (set_attr "mode" "TI")])
1991
1992 (define_insn "*mmx_pextrb_zext"
1993 [(set (match_operand:SWI248 0 "register_operand" "=r")
1994 (zero_extend:SWI248
1995 (vec_select:QI
1996 (match_operand:V8QI 1 "register_operand" "Yv")
1997 (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))]
1998 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1"
1999 "%vpextrb\t{%2, %1, %k0|%k0, %1, %2}"
2000 [(set_attr "type" "sselog1")
2001 (set_attr "prefix_data16" "1")
2002 (set_attr "prefix_extra" "1")
2003 (set_attr "length_immediate" "1")
2004 (set_attr "prefix" "maybe_vex")
2005 (set_attr "mode" "TI")])
2006
2007 (define_expand "mmx_pshufw"
2008 [(match_operand:V4HI 0 "register_operand")
2009 (match_operand:V4HI 1 "register_mmxmem_operand")
2010 (match_operand:SI 2 "const_int_operand")]
2011 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2012 && (TARGET_SSE || TARGET_3DNOW_A)"
2013 {
2014 int mask = INTVAL (operands[2]);
2015 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1],
2016 GEN_INT ((mask >> 0) & 3),
2017 GEN_INT ((mask >> 2) & 3),
2018 GEN_INT ((mask >> 4) & 3),
2019 GEN_INT ((mask >> 6) & 3)));
2020 DONE;
2021 })
2022
2023 (define_insn "mmx_pshufw_1"
2024 [(set (match_operand:V4HI 0 "register_operand" "=y,xYw")
2025 (vec_select:V4HI
2026 (match_operand:V4HI 1 "register_mmxmem_operand" "ym,xYw")
2027 (parallel [(match_operand 2 "const_0_to_3_operand")
2028 (match_operand 3 "const_0_to_3_operand")
2029 (match_operand 4 "const_0_to_3_operand")
2030 (match_operand 5 "const_0_to_3_operand")])))]
2031 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2032 && (TARGET_SSE || TARGET_3DNOW_A)"
2033 {
2034 int mask = 0;
2035 mask |= INTVAL (operands[2]) << 0;
2036 mask |= INTVAL (operands[3]) << 2;
2037 mask |= INTVAL (operands[4]) << 4;
2038 mask |= INTVAL (operands[5]) << 6;
2039 operands[2] = GEN_INT (mask);
2040
2041 switch (which_alternative)
2042 {
2043 case 0:
2044 return "pshufw\t{%2, %1, %0|%0, %1, %2}";
2045 case 1:
2046 return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}";
2047 default:
2048 gcc_unreachable ();
2049 }
2050 }
2051 [(set_attr "isa" "*,sse2")
2052 (set_attr "mmx_isa" "native,*")
2053 (set_attr "type" "mmxcvt,sselog1")
2054 (set_attr "length_immediate" "1")
2055 (set_attr "mode" "DI,TI")])
2056
2057 (define_insn "*mmx_pshufd_1"
2058 [(set (match_operand:V2SI 0 "register_operand" "=Yv")
2059 (vec_select:V2SI
2060 (match_operand:V2SI 1 "register_operand" "Yv")
2061 (parallel [(match_operand 2 "const_0_to_1_operand")
2062 (match_operand 3 "const_0_to_1_operand")])))]
2063 "TARGET_MMX_WITH_SSE"
2064 {
2065 int mask = 0;
2066 mask |= INTVAL (operands[2]) << 0;
2067 mask |= INTVAL (operands[3]) << 2;
2068 mask |= 2 << 4;
2069 mask |= 3 << 6;
2070 operands[2] = GEN_INT (mask);
2071
2072 return "%vpshufd\t{%2, %1, %0|%0, %1, %2}";
2073 }
2074 [(set_attr "type" "sselog1")
2075 (set_attr "prefix_data16" "1")
2076 (set_attr "length_immediate" "1")
2077 (set_attr "mode" "TI")])
2078
2079 (define_insn "mmx_pswapdv2si2"
2080 [(set (match_operand:V2SI 0 "register_operand" "=y,Yv")
2081 (vec_select:V2SI
2082 (match_operand:V2SI 1 "register_mmxmem_operand" "ym,Yv")
2083 (parallel [(const_int 1) (const_int 0)])))]
2084 "TARGET_3DNOW_A"
2085 "@
2086 pswapd\t{%1, %0|%0, %1}
2087 %vpshufd\t{$0xe1, %1, %0|%0, %1, 0xe1}";
2088 [(set_attr "isa" "*,sse2")
2089 (set_attr "mmx_isa" "native,*")
2090 (set_attr "type" "mmxcvt,sselog1")
2091 (set_attr "prefix_extra" "1,*")
2092 (set_attr "prefix_data16" "*,1")
2093 (set_attr "length_immediate" "*,1")
2094 (set_attr "mode" "DI,TI")])
2095
2096 (define_insn "*vec_dupv4hi"
2097 [(set (match_operand:V4HI 0 "register_operand" "=y,xYw")
2098 (vec_duplicate:V4HI
2099 (truncate:HI
2100 (match_operand:SI 1 "register_operand" "0,xYw"))))]
2101 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2102 && (TARGET_SSE || TARGET_3DNOW_A)"
2103 "@
2104 pshufw\t{$0, %0, %0|%0, %0, 0}
2105 %vpshuflw\t{$0, %1, %0|%0, %1, 0}"
2106 [(set_attr "isa" "*,sse2")
2107 (set_attr "mmx_isa" "native,*")
2108 (set_attr "type" "mmxcvt,sselog1")
2109 (set_attr "length_immediate" "1")
2110 (set_attr "mode" "DI,TI")])
2111
2112
2113 (define_insn "*vec_dupv2si"
2114 [(set (match_operand:V2SI 0 "register_operand" "=y,Yv")
2115 (vec_duplicate:V2SI
2116 (match_operand:SI 1 "register_operand" "0,Yv")))]
2117 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2118 "@
2119 punpckldq\t%0, %0
2120 %vpshufd\t{$0xe0, %1, %0|%0, %1, 0xe0}"
2121 [(set_attr "isa" "*,sse2")
2122 (set_attr "mmx_isa" "native,*")
2123 (set_attr "type" "mmxcvt,sselog1")
2124 (set_attr "prefix_data16" "*,1")
2125 (set_attr "length_immediate" "*,1")
2126 (set_attr "mode" "DI,TI")])
2127
2128 (define_insn "*mmx_concatv2si"
2129 [(set (match_operand:V2SI 0 "register_operand" "=y,y")
2130 (vec_concat:V2SI
2131 (match_operand:SI 1 "nonimmediate_operand" " 0,rm")
2132 (match_operand:SI 2 "nonimm_or_0_operand" "ym,C")))]
2133 "TARGET_MMX && !TARGET_SSE"
2134 "@
2135 punpckldq\t{%2, %0|%0, %2}
2136 movd\t{%1, %0|%0, %1}"
2137 [(set_attr "type" "mmxcvt,mmxmov")
2138 (set_attr "mode" "DI")])
2139
2140 (define_expand "vec_setv2si"
2141 [(match_operand:V2SI 0 "register_operand")
2142 (match_operand:SI 1 "register_operand")
2143 (match_operand 2 "const_int_operand")]
2144 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2145 {
2146 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
2147 INTVAL (operands[2]));
2148 DONE;
2149 })
2150
2151 ;; Avoid combining registers from different units in a single alternative,
2152 ;; see comment above inline_secondary_memory_needed function in i386.c
2153 (define_insn_and_split "*vec_extractv2si_0"
2154 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r,r")
2155 (vec_select:SI
2156 (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m,x")
2157 (parallel [(const_int 0)])))]
2158 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2159 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2160 "#"
2161 "&& reload_completed"
2162 [(set (match_dup 0) (match_dup 1))]
2163 "operands[1] = gen_lowpart (SImode, operands[1]);"
2164 [(set_attr "isa" "*,*,*,*,*,sse2")
2165 (set_attr "mmx_isa" "*,*,native,native,*,*")
2166 (set (attr "preferred_for_speed")
2167 (cond [(eq_attr "alternative" "5")
2168 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2169 ]
2170 (symbol_ref "true")))])
2171
2172 (define_insn "*vec_extractv2si_0_zext_sse4"
2173 [(set (match_operand:DI 0 "register_operand" "=r,x")
2174 (zero_extend:DI
2175 (vec_select:SI
2176 (match_operand:V2SI 1 "register_operand" "x,x")
2177 (parallel [(const_int 0)]))))]
2178 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE4_1"
2179 "#"
2180 [(set_attr "isa" "x64,*")
2181 (set (attr "preferred_for_speed")
2182 (cond [(eq_attr "alternative" "0")
2183 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2184 ]
2185 (symbol_ref "true")))])
2186
2187 (define_insn "*vec_extractv2si_0_zext"
2188 [(set (match_operand:DI 0 "register_operand" "=r")
2189 (zero_extend:DI
2190 (vec_select:SI
2191 (match_operand:V2SI 1 "register_operand" "x")
2192 (parallel [(const_int 0)]))))]
2193 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2194 && TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_FROM_VEC"
2195 "#")
2196
2197 (define_split
2198 [(set (match_operand:DI 0 "register_operand")
2199 (zero_extend:DI
2200 (vec_select:SI
2201 (match_operand:V2SI 1 "register_operand")
2202 (parallel [(const_int 0)]))))]
2203 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2204 && TARGET_SSE2 && reload_completed"
2205 [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
2206 "operands[1] = gen_lowpart (SImode, operands[1]);")
2207
2208 ;; Avoid combining registers from different units in a single alternative,
2209 ;; see comment above inline_secondary_memory_needed function in i386.c
2210 (define_insn "*vec_extractv2si_1"
2211 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,rm,x,x,y,x,r")
2212 (vec_select:SI
2213 (match_operand:V2SI 1 "nonimmediate_operand" " 0,x ,x,0,o,o,o")
2214 (parallel [(const_int 1)])))]
2215 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2216 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2217 "@
2218 punpckhdq\t%0, %0
2219 %vpextrd\t{$1, %1, %0|%0, %1, 1}
2220 %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5}
2221 shufps\t{$0xe5, %0, %0|%0, %0, 0xe5}
2222 #
2223 #
2224 #"
2225 [(set_attr "isa" "*,sse4,sse2,noavx,*,*,*")
2226 (set_attr "mmx_isa" "native,*,*,*,native,*,*")
2227 (set_attr "type" "mmxcvt,ssemov,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
2228 (set (attr "length_immediate")
2229 (if_then_else (eq_attr "alternative" "1,2,3")
2230 (const_string "1")
2231 (const_string "*")))
2232 (set_attr "prefix" "orig,maybe_vex,maybe_vex,orig,orig,orig,orig")
2233 (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
2234
2235 (define_split
2236 [(set (match_operand:SI 0 "register_operand")
2237 (vec_select:SI
2238 (match_operand:V2SI 1 "memory_operand")
2239 (parallel [(const_int 1)])))]
2240 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed"
2241 [(set (match_dup 0) (match_dup 1))]
2242 "operands[1] = adjust_address (operands[1], SImode, 4);")
2243
2244 (define_insn "*vec_extractv2si_1_zext"
2245 [(set (match_operand:DI 0 "register_operand" "=r")
2246 (zero_extend:DI
2247 (vec_select:SI
2248 (match_operand:V2SI 1 "register_operand" "x")
2249 (parallel [(const_int 1)]))))]
2250 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2251 && TARGET_64BIT && TARGET_SSE4_1"
2252 "%vpextrd\t{$1, %1, %k0|%k0, %1, 1}"
2253 [(set_attr "type" "sselog1")
2254 (set_attr "prefix_extra" "1")
2255 (set_attr "length_immediate" "1")
2256 (set_attr "prefix" "maybe_vex")
2257 (set_attr "mode" "TI")])
2258
2259 (define_insn_and_split "*vec_extractv2si_zext_mem"
2260 [(set (match_operand:DI 0 "register_operand" "=y,x,r")
2261 (zero_extend:DI
2262 (vec_select:SI
2263 (match_operand:V2SI 1 "memory_operand" "o,o,o")
2264 (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
2265 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_64BIT"
2266 "#"
2267 "&& reload_completed"
2268 [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
2269 {
2270 operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4);
2271 }
2272 [(set_attr "isa" "*,sse2,*")
2273 (set_attr "mmx_isa" "native,*,*")])
2274
2275 (define_expand "vec_extractv2sisi"
2276 [(match_operand:SI 0 "register_operand")
2277 (match_operand:V2SI 1 "register_operand")
2278 (match_operand 2 "const_int_operand")]
2279 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2280 {
2281 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
2282 operands[1], INTVAL (operands[2]));
2283 DONE;
2284 })
2285
2286 (define_expand "vec_initv2sisi"
2287 [(match_operand:V2SI 0 "register_operand")
2288 (match_operand 1)]
2289 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
2290 {
2291 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
2292 operands[1]);
2293 DONE;
2294 })
2295
2296 (define_expand "vec_setv4hi"
2297 [(match_operand:V4HI 0 "register_operand")
2298 (match_operand:HI 1 "register_operand")
2299 (match_operand 2 "const_int_operand")]
2300 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2301 {
2302 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
2303 INTVAL (operands[2]));
2304 DONE;
2305 })
2306
2307 (define_expand "vec_extractv4hihi"
2308 [(match_operand:HI 0 "register_operand")
2309 (match_operand:V4HI 1 "register_operand")
2310 (match_operand 2 "const_int_operand")]
2311 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2312 {
2313 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
2314 operands[1], INTVAL (operands[2]));
2315 DONE;
2316 })
2317
2318 (define_expand "vec_initv4hihi"
2319 [(match_operand:V4HI 0 "register_operand")
2320 (match_operand 1)]
2321 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
2322 {
2323 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
2324 operands[1]);
2325 DONE;
2326 })
2327
2328 (define_expand "vec_setv8qi"
2329 [(match_operand:V8QI 0 "register_operand")
2330 (match_operand:QI 1 "register_operand")
2331 (match_operand 2 "const_int_operand")]
2332 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2333 {
2334 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1],
2335 INTVAL (operands[2]));
2336 DONE;
2337 })
2338
2339 (define_expand "vec_extractv8qiqi"
2340 [(match_operand:QI 0 "register_operand")
2341 (match_operand:V8QI 1 "register_operand")
2342 (match_operand 2 "const_int_operand")]
2343 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2344 {
2345 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0],
2346 operands[1], INTVAL (operands[2]));
2347 DONE;
2348 })
2349
2350 (define_expand "vec_initv8qiqi"
2351 [(match_operand:V8QI 0 "register_operand")
2352 (match_operand 1)]
2353 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE"
2354 {
2355 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0],
2356 operands[1]);
2357 DONE;
2358 })
2359
2360 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2361 ;;
2362 ;; Miscellaneous
2363 ;;
2364 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2365
2366 (define_expand "mmx_uavg<mode>3"
2367 [(set (match_operand:MMXMODE12 0 "register_operand")
2368 (truncate:MMXMODE12
2369 (lshiftrt:<mmxdoublemode>
2370 (plus:<mmxdoublemode>
2371 (plus:<mmxdoublemode>
2372 (zero_extend:<mmxdoublemode>
2373 (match_operand:MMXMODE12 1 "register_mmxmem_operand"))
2374 (zero_extend:<mmxdoublemode>
2375 (match_operand:MMXMODE12 2 "register_mmxmem_operand")))
2376 (match_dup 3))
2377 (const_int 1))))]
2378 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2379 && (TARGET_SSE || TARGET_3DNOW)"
2380 {
2381 operands[3] = CONST1_RTX(<mmxdoublemode>mode);
2382 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
2383 })
2384
2385 (define_insn "*mmx_uavgv8qi3"
2386 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
2387 (truncate:V8QI
2388 (lshiftrt:V8HI
2389 (plus:V8HI
2390 (plus:V8HI
2391 (zero_extend:V8HI
2392 (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yv"))
2393 (zero_extend:V8HI
2394 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")))
2395 (const_vector:V8HI [(const_int 1) (const_int 1)
2396 (const_int 1) (const_int 1)
2397 (const_int 1) (const_int 1)
2398 (const_int 1) (const_int 1)]))
2399 (const_int 1))))]
2400 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2401 && (TARGET_SSE || TARGET_3DNOW)
2402 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2403 {
2404 switch (which_alternative)
2405 {
2406 case 2:
2407 return "vpavgb\t{%2, %1, %0|%0, %1, %2}";
2408 case 1:
2409 case 0:
2410 /* These two instructions have the same operation, but their encoding
2411 is different. Prefer the one that is de facto standard. */
2412 if (TARGET_SSE || TARGET_3DNOW_A)
2413 return "pavgb\t{%2, %0|%0, %2}";
2414 else
2415 return "pavgusb\t{%2, %0|%0, %2}";
2416 default:
2417 gcc_unreachable ();
2418 }
2419 }
2420 [(set_attr "isa" "*,sse2_noavx,avx")
2421 (set_attr "mmx_isa" "native,*,*")
2422 (set_attr "type" "mmxshft,sseiadd,sseiadd")
2423 (set (attr "prefix_extra")
2424 (if_then_else
2425 (not (ior (match_test "TARGET_SSE")
2426 (match_test "TARGET_3DNOW_A")))
2427 (const_string "1")
2428 (const_string "*")))
2429 (set_attr "mode" "DI,TI,TI")])
2430
2431 (define_insn "*mmx_uavgv4hi3"
2432 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
2433 (truncate:V4HI
2434 (lshiftrt:V4SI
2435 (plus:V4SI
2436 (plus:V4SI
2437 (zero_extend:V4SI
2438 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv"))
2439 (zero_extend:V4SI
2440 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))
2441 (const_vector:V4SI [(const_int 1) (const_int 1)
2442 (const_int 1) (const_int 1)]))
2443 (const_int 1))))]
2444 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2445 && (TARGET_SSE || TARGET_3DNOW_A)
2446 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
2447 "@
2448 pavgw\t{%2, %0|%0, %2}
2449 pavgw\t{%2, %0|%0, %2}
2450 vpavgw\t{%2, %1, %0|%0, %1, %2}"
2451 [(set_attr "isa" "*,sse2_noavx,avx")
2452 (set_attr "mmx_isa" "native,*,*")
2453 (set_attr "type" "mmxshft,sseiadd,sseiadd")
2454 (set_attr "mode" "DI,TI,TI")])
2455
2456 (define_expand "uavg<mode>3_ceil"
2457 [(set (match_operand:MMXMODE12 0 "register_operand")
2458 (truncate:MMXMODE12
2459 (lshiftrt:<mmxdoublemode>
2460 (plus:<mmxdoublemode>
2461 (plus:<mmxdoublemode>
2462 (zero_extend:<mmxdoublemode>
2463 (match_operand:MMXMODE12 1 "register_operand"))
2464 (zero_extend:<mmxdoublemode>
2465 (match_operand:MMXMODE12 2 "register_operand")))
2466 (match_dup 3))
2467 (const_int 1))))]
2468 "TARGET_MMX_WITH_SSE"
2469 {
2470 operands[3] = CONST1_RTX(<mmxdoublemode>mode);
2471 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
2472 })
2473
2474 (define_insn "mmx_psadbw"
2475 [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv")
2476 (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0,0,Yv")
2477 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")]
2478 UNSPEC_PSADBW))]
2479 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2480 && (TARGET_SSE || TARGET_3DNOW_A)"
2481 "@
2482 psadbw\t{%2, %0|%0, %2}
2483 psadbw\t{%2, %0|%0, %2}
2484 vpsadbw\t{%2, %1, %0|%0, %1, %2}"
2485 [(set_attr "isa" "*,sse2_noavx,avx")
2486 (set_attr "mmx_isa" "native,*,*")
2487 (set_attr "type" "mmxshft,sseiadd,sseiadd")
2488 (set_attr "mode" "DI,TI,TI")])
2489
2490 (define_expand "reduc_plus_scal_v8qi"
2491 [(plus:V8QI
2492 (match_operand:QI 0 "register_operand")
2493 (match_operand:V8QI 1 "register_operand"))]
2494 "TARGET_MMX_WITH_SSE"
2495 {
2496 rtx tmp = gen_reg_rtx (V8QImode);
2497 emit_move_insn (tmp, CONST0_RTX (V8QImode));
2498 rtx tmp2 = gen_reg_rtx (V1DImode);
2499 emit_insn (gen_mmx_psadbw (tmp2, operands[1], tmp));
2500 tmp2 = gen_lowpart (V8QImode, tmp2);
2501 emit_insn (gen_vec_extractv8qiqi (operands[0], tmp2, const0_rtx));
2502 DONE;
2503 })
2504
2505 (define_expand "usadv8qi"
2506 [(match_operand:V2SI 0 "register_operand")
2507 (match_operand:V8QI 1 "register_operand")
2508 (match_operand:V8QI 2 "register_operand")
2509 (match_operand:V2SI 3 "register_operand")]
2510 "TARGET_MMX_WITH_SSE"
2511 {
2512 rtx t1 = gen_reg_rtx (V1DImode);
2513 rtx t2 = gen_reg_rtx (V2SImode);
2514 emit_insn (gen_mmx_psadbw (t1, operands[1], operands[2]));
2515 convert_move (t2, t1, 0);
2516 emit_insn (gen_addv2si3 (operands[0], t2, operands[3]));
2517 DONE;
2518 })
2519
2520 (define_insn_and_split "mmx_pmovmskb"
2521 [(set (match_operand:SI 0 "register_operand" "=r,r")
2522 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y,x")]
2523 UNSPEC_MOVMSK))]
2524 "(TARGET_MMX || TARGET_MMX_WITH_SSE)
2525 && (TARGET_SSE || TARGET_3DNOW_A)"
2526 "@
2527 pmovmskb\t{%1, %0|%0, %1}
2528 #"
2529 "TARGET_SSE2 && reload_completed
2530 && SSE_REGNO_P (REGNO (operands[1]))"
2531 [(set (match_dup 0)
2532 (unspec:SI [(match_dup 1)] UNSPEC_MOVMSK))
2533 (set (match_dup 0)
2534 (zero_extend:SI (match_dup 2)))]
2535 {
2536 /* Generate SSE pmovmskb and zero-extend from QImode to SImode. */
2537 operands[1] = lowpart_subreg (V16QImode, operands[1],
2538 GET_MODE (operands[1]));
2539 operands[2] = lowpart_subreg (QImode, operands[0],
2540 GET_MODE (operands[0]));
2541 }
2542 [(set_attr "mmx_isa" "native,sse")
2543 (set_attr "type" "mmxcvt,ssemov")
2544 (set_attr "mode" "DI,TI")])
2545
2546 (define_expand "mmx_maskmovq"
2547 [(set (match_operand:V8QI 0 "memory_operand")
2548 (unspec:V8QI [(match_operand:V8QI 1 "register_operand")
2549 (match_operand:V8QI 2 "register_operand")
2550 (match_dup 0)]
2551 UNSPEC_MASKMOV))]
2552 "TARGET_SSE || TARGET_3DNOW_A")
2553
2554 (define_insn "*mmx_maskmovq"
2555 [(set (mem:V8QI (match_operand:P 0 "register_operand" "D"))
2556 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
2557 (match_operand:V8QI 2 "register_operand" "y")
2558 (mem:V8QI (match_dup 0))]
2559 UNSPEC_MASKMOV))]
2560 "TARGET_SSE || TARGET_3DNOW_A"
2561 ;; @@@ check ordering of operands in intel/nonintel syntax
2562 "maskmovq\t{%2, %1|%1, %2}"
2563 [(set_attr "type" "mmxcvt")
2564 (set_attr "znver1_decode" "vector")
2565 (set_attr "mode" "DI")])
2566
2567 (define_int_iterator EMMS
2568 [(UNSPECV_EMMS "TARGET_MMX")
2569 (UNSPECV_FEMMS "TARGET_3DNOW")])
2570
2571 (define_int_attr emms
2572 [(UNSPECV_EMMS "emms")
2573 (UNSPECV_FEMMS "femms")])
2574
2575 (define_expand "mmx_<emms>"
2576 [(parallel
2577 [(unspec_volatile [(const_int 0)] EMMS)
2578 (clobber (reg:XF ST0_REG))
2579 (clobber (reg:XF ST1_REG))
2580 (clobber (reg:XF ST2_REG))
2581 (clobber (reg:XF ST3_REG))
2582 (clobber (reg:XF ST4_REG))
2583 (clobber (reg:XF ST5_REG))
2584 (clobber (reg:XF ST6_REG))
2585 (clobber (reg:XF ST7_REG))
2586 (clobber (reg:DI MM0_REG))
2587 (clobber (reg:DI MM1_REG))
2588 (clobber (reg:DI MM2_REG))
2589 (clobber (reg:DI MM3_REG))
2590 (clobber (reg:DI MM4_REG))
2591 (clobber (reg:DI MM5_REG))
2592 (clobber (reg:DI MM6_REG))
2593 (clobber (reg:DI MM7_REG))])]
2594 "TARGET_MMX || TARGET_MMX_WITH_SSE"
2595 {
2596 if (!TARGET_MMX)
2597 {
2598 emit_insn (gen_nop ());
2599 DONE;
2600 }
2601 })
2602
2603 (define_insn "*mmx_<emms>"
2604 [(unspec_volatile [(const_int 0)] EMMS)
2605 (clobber (reg:XF ST0_REG))
2606 (clobber (reg:XF ST1_REG))
2607 (clobber (reg:XF ST2_REG))
2608 (clobber (reg:XF ST3_REG))
2609 (clobber (reg:XF ST4_REG))
2610 (clobber (reg:XF ST5_REG))
2611 (clobber (reg:XF ST6_REG))
2612 (clobber (reg:XF ST7_REG))
2613 (clobber (reg:DI MM0_REG))
2614 (clobber (reg:DI MM1_REG))
2615 (clobber (reg:DI MM2_REG))
2616 (clobber (reg:DI MM3_REG))
2617 (clobber (reg:DI MM4_REG))
2618 (clobber (reg:DI MM5_REG))
2619 (clobber (reg:DI MM6_REG))
2620 (clobber (reg:DI MM7_REG))]
2621 ""
2622 "<emms>"
2623 [(set_attr "type" "mmx")
2624 (set_attr "modrm" "0")
2625 (set_attr "memory" "none")])