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