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