Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/powerpcspe/vector.md @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 ;; Expander definitions for vector support between altivec & vsx. No | |
2 ;; instructions are in this file, this file provides the generic vector | |
3 ;; expander, and the actual vector instructions will be in altivec.md and | |
4 ;; vsx.md | |
5 | |
6 ;; Copyright (C) 2009-2017 Free Software Foundation, Inc. | |
7 ;; Contributed by Michael Meissner <meissner@linux.vnet.ibm.com> | |
8 | |
9 ;; This file is part of GCC. | |
10 | |
11 ;; GCC is free software; you can redistribute it and/or modify it | |
12 ;; under the terms of the GNU General Public License as published | |
13 ;; by the Free Software Foundation; either version 3, or (at your | |
14 ;; option) any later version. | |
15 | |
16 ;; GCC is distributed in the hope that it will be useful, but WITHOUT | |
17 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
18 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
19 ;; License for more details. | |
20 | |
21 ;; You should have received a copy of the GNU General Public License | |
22 ;; along with GCC; see the file COPYING3. If not see | |
23 ;; <http://www.gnu.org/licenses/>. | |
24 | |
25 | |
26 ;; Vector int modes | |
27 (define_mode_iterator VEC_I [V16QI V8HI V4SI V2DI]) | |
28 | |
29 ;; Vector int modes for parity | |
30 (define_mode_iterator VEC_IP [V8HI | |
31 V4SI | |
32 V2DI | |
33 V1TI | |
34 (TI "TARGET_VSX_TIMODE")]) | |
35 | |
36 ;; Vector float modes | |
37 (define_mode_iterator VEC_F [V4SF V2DF]) | |
38 | |
39 ;; Vector arithmetic modes | |
40 (define_mode_iterator VEC_A [V16QI V8HI V4SI V2DI V4SF V2DF]) | |
41 | |
42 ;; Vector modes that need alginment via permutes | |
43 (define_mode_iterator VEC_K [V16QI V8HI V4SI V4SF]) | |
44 | |
45 ;; Vector logical modes | |
46 (define_mode_iterator VEC_L [V16QI V8HI V4SI V2DI V4SF V2DF V1TI TI KF TF]) | |
47 | |
48 ;; Vector modes for moves. Don't do TImode or TFmode here, since their | |
49 ;; moves are handled elsewhere. | |
50 (define_mode_iterator VEC_M [V16QI V8HI V4SI V2DI V4SF V2DF V1TI KF]) | |
51 | |
52 ;; Vector modes for types that don't need a realignment under VSX | |
53 (define_mode_iterator VEC_N [V4SI V4SF V2DI V2DF V1TI KF TF]) | |
54 | |
55 ;; Vector comparison modes | |
56 (define_mode_iterator VEC_C [V16QI V8HI V4SI V2DI V4SF V2DF]) | |
57 | |
58 ;; Vector init/extract modes | |
59 (define_mode_iterator VEC_E [V16QI V8HI V4SI V2DI V4SF V2DF]) | |
60 | |
61 ;; Vector modes for 64-bit base types | |
62 (define_mode_iterator VEC_64 [V2DI V2DF]) | |
63 | |
64 ;; Vector integer modes | |
65 (define_mode_iterator VI [V4SI V8HI V16QI]) | |
66 | |
67 ;; Base type from vector mode | |
68 (define_mode_attr VEC_base [(V16QI "QI") | |
69 (V8HI "HI") | |
70 (V4SI "SI") | |
71 (V2DI "DI") | |
72 (V4SF "SF") | |
73 (V2DF "DF") | |
74 (V1TI "TI") | |
75 (TI "TI")]) | |
76 | |
77 ;; As above, but in lower case | |
78 (define_mode_attr VEC_base_l [(V16QI "qi") | |
79 (V8HI "hi") | |
80 (V4SI "si") | |
81 (V2DI "di") | |
82 (V4SF "sf") | |
83 (V2DF "df") | |
84 (V1TI "ti") | |
85 (TI "ti")]) | |
86 | |
87 ;; Same size integer type for floating point data | |
88 (define_mode_attr VEC_int [(V4SF "v4si") | |
89 (V2DF "v2di")]) | |
90 | |
91 (define_mode_attr VEC_INT [(V4SF "V4SI") | |
92 (V2DF "V2DI")]) | |
93 | |
94 ;; constants for unspec | |
95 (define_c_enum "unspec" [UNSPEC_PREDICATE | |
96 UNSPEC_REDUC | |
97 UNSPEC_NEZ_P]) | |
98 | |
99 ;; Vector reduction code iterators | |
100 (define_code_iterator VEC_reduc [plus smin smax]) | |
101 | |
102 (define_code_attr VEC_reduc_name [(plus "plus") | |
103 (smin "smin") | |
104 (smax "smax")]) | |
105 | |
106 (define_code_attr VEC_reduc_rtx [(plus "add") | |
107 (smin "smin") | |
108 (smax "smax")]) | |
109 | |
110 | |
111 ;; Vector move instructions. Little-endian VSX loads and stores require | |
112 ;; special handling to circumvent "element endianness." | |
113 (define_expand "mov<mode>" | |
114 [(set (match_operand:VEC_M 0 "nonimmediate_operand" "") | |
115 (match_operand:VEC_M 1 "any_operand" ""))] | |
116 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
117 { | |
118 if (can_create_pseudo_p ()) | |
119 { | |
120 if (CONSTANT_P (operands[1])) | |
121 { | |
122 if (FLOAT128_VECTOR_P (<MODE>mode)) | |
123 { | |
124 if (!easy_fp_constant (operands[1], <MODE>mode)) | |
125 operands[1] = force_const_mem (<MODE>mode, operands[1]); | |
126 } | |
127 else if (!easy_vector_constant (operands[1], <MODE>mode)) | |
128 operands[1] = force_const_mem (<MODE>mode, operands[1]); | |
129 } | |
130 | |
131 if (!vlogical_operand (operands[0], <MODE>mode) | |
132 && !vlogical_operand (operands[1], <MODE>mode)) | |
133 operands[1] = force_reg (<MODE>mode, operands[1]); | |
134 } | |
135 if (!BYTES_BIG_ENDIAN | |
136 && VECTOR_MEM_VSX_P (<MODE>mode) | |
137 && !TARGET_P9_VECTOR | |
138 && !gpr_or_gpr_p (operands[0], operands[1]) | |
139 && (memory_operand (operands[0], <MODE>mode) | |
140 ^ memory_operand (operands[1], <MODE>mode))) | |
141 { | |
142 rs6000_emit_le_vsx_move (operands[0], operands[1], <MODE>mode); | |
143 DONE; | |
144 } | |
145 }) | |
146 | |
147 ;; Generic vector floating point load/store instructions. These will match | |
148 ;; insns defined in vsx.md or altivec.md depending on the switches. | |
149 (define_expand "vector_load_<mode>" | |
150 [(set (match_operand:VEC_M 0 "vfloat_operand" "") | |
151 (match_operand:VEC_M 1 "memory_operand" ""))] | |
152 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
153 "") | |
154 | |
155 (define_expand "vector_store_<mode>" | |
156 [(set (match_operand:VEC_M 0 "memory_operand" "") | |
157 (match_operand:VEC_M 1 "vfloat_operand" ""))] | |
158 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
159 "") | |
160 | |
161 ;; Splits if a GPR register was chosen for the move | |
162 (define_split | |
163 [(set (match_operand:VEC_L 0 "nonimmediate_operand" "") | |
164 (match_operand:VEC_L 1 "input_operand" ""))] | |
165 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode) | |
166 && reload_completed | |
167 && gpr_or_gpr_p (operands[0], operands[1]) | |
168 && !direct_move_p (operands[0], operands[1]) | |
169 && !quad_load_store_p (operands[0], operands[1])" | |
170 [(pc)] | |
171 { | |
172 rs6000_split_multireg_move (operands[0], operands[1]); | |
173 DONE; | |
174 }) | |
175 | |
176 ;; Vector floating point load/store instructions that uses the Altivec | |
177 ;; instructions even if we are compiling for VSX, since the Altivec | |
178 ;; instructions silently ignore the bottom 3 bits of the address, and VSX does | |
179 ;; not. | |
180 (define_expand "vector_altivec_load_<mode>" | |
181 [(set (match_operand:VEC_M 0 "vfloat_operand" "") | |
182 (match_operand:VEC_M 1 "memory_operand" ""))] | |
183 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
184 " | |
185 { | |
186 gcc_assert (VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)); | |
187 | |
188 if (VECTOR_MEM_VSX_P (<MODE>mode)) | |
189 { | |
190 operands[1] = rs6000_address_for_altivec (operands[1]); | |
191 rtx and_op = XEXP (operands[1], 0); | |
192 gcc_assert (GET_CODE (and_op) == AND); | |
193 rtx addr = XEXP (and_op, 0); | |
194 if (GET_CODE (addr) == PLUS) | |
195 emit_insn (gen_altivec_lvx_<mode>_2op (operands[0], XEXP (addr, 0), | |
196 XEXP (addr, 1))); | |
197 else | |
198 emit_insn (gen_altivec_lvx_<mode>_1op (operands[0], operands[1])); | |
199 DONE; | |
200 } | |
201 }") | |
202 | |
203 (define_expand "vector_altivec_store_<mode>" | |
204 [(set (match_operand:VEC_M 0 "memory_operand" "") | |
205 (match_operand:VEC_M 1 "vfloat_operand" ""))] | |
206 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
207 " | |
208 { | |
209 gcc_assert (VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)); | |
210 | |
211 if (VECTOR_MEM_VSX_P (<MODE>mode)) | |
212 { | |
213 operands[0] = rs6000_address_for_altivec (operands[0]); | |
214 rtx and_op = XEXP (operands[0], 0); | |
215 gcc_assert (GET_CODE (and_op) == AND); | |
216 rtx addr = XEXP (and_op, 0); | |
217 if (GET_CODE (addr) == PLUS) | |
218 emit_insn (gen_altivec_stvx_<mode>_2op (operands[1], XEXP (addr, 0), | |
219 XEXP (addr, 1))); | |
220 else | |
221 emit_insn (gen_altivec_stvx_<mode>_1op (operands[1], operands[0])); | |
222 DONE; | |
223 } | |
224 }") | |
225 | |
226 | |
227 | |
228 ;; Generic floating point vector arithmetic support | |
229 (define_expand "add<mode>3" | |
230 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
231 (plus:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") | |
232 (match_operand:VEC_F 2 "vfloat_operand" "")))] | |
233 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
234 "") | |
235 | |
236 (define_expand "sub<mode>3" | |
237 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
238 (minus:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") | |
239 (match_operand:VEC_F 2 "vfloat_operand" "")))] | |
240 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
241 "") | |
242 | |
243 (define_expand "mul<mode>3" | |
244 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
245 (mult:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") | |
246 (match_operand:VEC_F 2 "vfloat_operand" "")))] | |
247 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
248 { | |
249 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) | |
250 { | |
251 emit_insn (gen_altivec_mulv4sf3 (operands[0], operands[1], operands[2])); | |
252 DONE; | |
253 } | |
254 }) | |
255 | |
256 (define_expand "div<mode>3" | |
257 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
258 (div:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") | |
259 (match_operand:VEC_F 2 "vfloat_operand" "")))] | |
260 "VECTOR_UNIT_VSX_P (<MODE>mode)" | |
261 { | |
262 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode) | |
263 && can_create_pseudo_p () && flag_finite_math_only | |
264 && !flag_trapping_math && flag_reciprocal_math) | |
265 { | |
266 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true); | |
267 DONE; | |
268 } | |
269 }) | |
270 | |
271 (define_expand "neg<mode>2" | |
272 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
273 (neg:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] | |
274 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
275 " | |
276 { | |
277 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) | |
278 { | |
279 emit_insn (gen_altivec_negv4sf2 (operands[0], operands[1])); | |
280 DONE; | |
281 } | |
282 }") | |
283 | |
284 (define_expand "abs<mode>2" | |
285 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
286 (abs:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] | |
287 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
288 " | |
289 { | |
290 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) | |
291 { | |
292 emit_insn (gen_altivec_absv4sf2 (operands[0], operands[1])); | |
293 DONE; | |
294 } | |
295 }") | |
296 | |
297 (define_expand "smin<mode>3" | |
298 [(set (match_operand:VEC_F 0 "register_operand" "") | |
299 (smin:VEC_F (match_operand:VEC_F 1 "register_operand" "") | |
300 (match_operand:VEC_F 2 "register_operand" "")))] | |
301 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
302 "") | |
303 | |
304 (define_expand "smax<mode>3" | |
305 [(set (match_operand:VEC_F 0 "register_operand" "") | |
306 (smax:VEC_F (match_operand:VEC_F 1 "register_operand" "") | |
307 (match_operand:VEC_F 2 "register_operand" "")))] | |
308 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
309 "") | |
310 | |
311 | |
312 (define_expand "sqrt<mode>2" | |
313 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
314 (sqrt:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] | |
315 "VECTOR_UNIT_VSX_P (<MODE>mode)" | |
316 { | |
317 if (<MODE>mode == V4SFmode | |
318 && !optimize_function_for_size_p (cfun) | |
319 && flag_finite_math_only && !flag_trapping_math | |
320 && flag_unsafe_math_optimizations) | |
321 { | |
322 rs6000_emit_swsqrt (operands[0], operands[1], 0); | |
323 DONE; | |
324 } | |
325 }) | |
326 | |
327 (define_expand "rsqrte<mode>2" | |
328 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
329 (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "")] | |
330 UNSPEC_RSQRT))] | |
331 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
332 "") | |
333 | |
334 (define_expand "re<mode>2" | |
335 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
336 (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "f")] | |
337 UNSPEC_FRES))] | |
338 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
339 "") | |
340 | |
341 (define_expand "ftrunc<mode>2" | |
342 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
343 (fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] | |
344 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
345 "") | |
346 | |
347 (define_expand "vector_ceil<mode>2" | |
348 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
349 (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "")] | |
350 UNSPEC_FRIP))] | |
351 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
352 "") | |
353 | |
354 (define_expand "vector_floor<mode>2" | |
355 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
356 (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "")] | |
357 UNSPEC_FRIM))] | |
358 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
359 "") | |
360 | |
361 (define_expand "vector_btrunc<mode>2" | |
362 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
363 (fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "")))] | |
364 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
365 "") | |
366 | |
367 (define_expand "vector_copysign<mode>3" | |
368 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
369 (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand" "") | |
370 (match_operand:VEC_F 2 "vfloat_operand" "")] UNSPEC_COPYSIGN))] | |
371 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
372 " | |
373 { | |
374 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) | |
375 { | |
376 emit_insn (gen_altivec_copysign_v4sf3 (operands[0], operands[1], | |
377 operands[2])); | |
378 DONE; | |
379 } | |
380 }") | |
381 | |
382 | |
383 ;; Vector comparisons | |
384 (define_expand "vcond<mode><mode>" | |
385 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
386 (if_then_else:VEC_F | |
387 (match_operator 3 "comparison_operator" | |
388 [(match_operand:VEC_F 4 "vfloat_operand" "") | |
389 (match_operand:VEC_F 5 "vfloat_operand" "")]) | |
390 (match_operand:VEC_F 1 "vfloat_operand" "") | |
391 (match_operand:VEC_F 2 "vfloat_operand" "")))] | |
392 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
393 " | |
394 { | |
395 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], | |
396 operands[3], operands[4], operands[5])) | |
397 DONE; | |
398 else | |
399 FAIL; | |
400 }") | |
401 | |
402 (define_expand "vcond<mode><mode>" | |
403 [(set (match_operand:VEC_I 0 "vint_operand") | |
404 (if_then_else:VEC_I | |
405 (match_operator 3 "comparison_operator" | |
406 [(match_operand:VEC_I 4 "vint_operand") | |
407 (match_operand:VEC_I 5 "vint_operand")]) | |
408 (match_operand:VEC_I 1 "vector_int_reg_or_same_bit") | |
409 (match_operand:VEC_I 2 "vector_int_reg_or_same_bit")))] | |
410 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
411 " | |
412 { | |
413 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], | |
414 operands[3], operands[4], operands[5])) | |
415 DONE; | |
416 else | |
417 FAIL; | |
418 }") | |
419 | |
420 (define_expand "vcondv4sfv4si" | |
421 [(set (match_operand:V4SF 0 "vfloat_operand" "") | |
422 (if_then_else:V4SF | |
423 (match_operator 3 "comparison_operator" | |
424 [(match_operand:V4SI 4 "vint_operand" "") | |
425 (match_operand:V4SI 5 "vint_operand" "")]) | |
426 (match_operand:V4SF 1 "vfloat_operand" "") | |
427 (match_operand:V4SF 2 "vfloat_operand" "")))] | |
428 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) | |
429 && VECTOR_UNIT_ALTIVEC_P (V4SImode)" | |
430 " | |
431 { | |
432 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], | |
433 operands[3], operands[4], operands[5])) | |
434 DONE; | |
435 else | |
436 FAIL; | |
437 }") | |
438 | |
439 (define_expand "vcondv4siv4sf" | |
440 [(set (match_operand:V4SI 0 "vint_operand" "") | |
441 (if_then_else:V4SI | |
442 (match_operator 3 "comparison_operator" | |
443 [(match_operand:V4SF 4 "vfloat_operand" "") | |
444 (match_operand:V4SF 5 "vfloat_operand" "")]) | |
445 (match_operand:V4SI 1 "vint_operand" "") | |
446 (match_operand:V4SI 2 "vint_operand" "")))] | |
447 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) | |
448 && VECTOR_UNIT_ALTIVEC_P (V4SImode)" | |
449 " | |
450 { | |
451 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], | |
452 operands[3], operands[4], operands[5])) | |
453 DONE; | |
454 else | |
455 FAIL; | |
456 }") | |
457 | |
458 (define_expand "vcondu<mode><mode>" | |
459 [(set (match_operand:VEC_I 0 "vint_operand") | |
460 (if_then_else:VEC_I | |
461 (match_operator 3 "comparison_operator" | |
462 [(match_operand:VEC_I 4 "vint_operand") | |
463 (match_operand:VEC_I 5 "vint_operand")]) | |
464 (match_operand:VEC_I 1 "vector_int_reg_or_same_bit") | |
465 (match_operand:VEC_I 2 "vector_int_reg_or_same_bit")))] | |
466 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
467 " | |
468 { | |
469 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], | |
470 operands[3], operands[4], operands[5])) | |
471 DONE; | |
472 else | |
473 FAIL; | |
474 }") | |
475 | |
476 (define_expand "vconduv4sfv4si" | |
477 [(set (match_operand:V4SF 0 "vfloat_operand" "") | |
478 (if_then_else:V4SF | |
479 (match_operator 3 "comparison_operator" | |
480 [(match_operand:V4SI 4 "vint_operand" "") | |
481 (match_operand:V4SI 5 "vint_operand" "")]) | |
482 (match_operand:V4SF 1 "vfloat_operand" "") | |
483 (match_operand:V4SF 2 "vfloat_operand" "")))] | |
484 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) | |
485 && VECTOR_UNIT_ALTIVEC_P (V4SImode)" | |
486 " | |
487 { | |
488 if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], | |
489 operands[3], operands[4], operands[5])) | |
490 DONE; | |
491 else | |
492 FAIL; | |
493 }") | |
494 | |
495 (define_expand "vector_eq<mode>" | |
496 [(set (match_operand:VEC_C 0 "vlogical_operand" "") | |
497 (eq:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "") | |
498 (match_operand:VEC_C 2 "vlogical_operand" "")))] | |
499 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
500 "") | |
501 | |
502 (define_expand "vector_gt<mode>" | |
503 [(set (match_operand:VEC_C 0 "vlogical_operand" "") | |
504 (gt:VEC_C (match_operand:VEC_C 1 "vlogical_operand" "") | |
505 (match_operand:VEC_C 2 "vlogical_operand" "")))] | |
506 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
507 "") | |
508 | |
509 (define_expand "vector_ge<mode>" | |
510 [(set (match_operand:VEC_F 0 "vlogical_operand" "") | |
511 (ge:VEC_F (match_operand:VEC_F 1 "vlogical_operand" "") | |
512 (match_operand:VEC_F 2 "vlogical_operand" "")))] | |
513 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
514 "") | |
515 | |
516 ; >= for integer vectors: swap operands and apply not-greater-than | |
517 (define_expand "vector_nlt<mode>" | |
518 [(set (match_operand:VEC_I 3 "vlogical_operand" "") | |
519 (gt:VEC_I (match_operand:VEC_I 2 "vlogical_operand" "") | |
520 (match_operand:VEC_I 1 "vlogical_operand" ""))) | |
521 (set (match_operand:VEC_I 0 "vlogical_operand" "") | |
522 (not:VEC_I (match_dup 3)))] | |
523 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
524 " | |
525 { | |
526 operands[3] = gen_reg_rtx_and_attrs (operands[0]); | |
527 }") | |
528 | |
529 (define_expand "vector_gtu<mode>" | |
530 [(set (match_operand:VEC_I 0 "vint_operand" "") | |
531 (gtu:VEC_I (match_operand:VEC_I 1 "vint_operand" "") | |
532 (match_operand:VEC_I 2 "vint_operand" "")))] | |
533 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
534 "") | |
535 | |
536 ; >= for integer vectors: swap operands and apply not-greater-than | |
537 (define_expand "vector_nltu<mode>" | |
538 [(set (match_operand:VEC_I 3 "vlogical_operand" "") | |
539 (gtu:VEC_I (match_operand:VEC_I 2 "vlogical_operand" "") | |
540 (match_operand:VEC_I 1 "vlogical_operand" ""))) | |
541 (set (match_operand:VEC_I 0 "vlogical_operand" "") | |
542 (not:VEC_I (match_dup 3)))] | |
543 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
544 " | |
545 { | |
546 operands[3] = gen_reg_rtx_and_attrs (operands[0]); | |
547 }") | |
548 | |
549 (define_expand "vector_geu<mode>" | |
550 [(set (match_operand:VEC_I 0 "vint_operand" "") | |
551 (geu:VEC_I (match_operand:VEC_I 1 "vint_operand" "") | |
552 (match_operand:VEC_I 2 "vint_operand" "")))] | |
553 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
554 "") | |
555 | |
556 ; <= for integer vectors: apply not-greater-than | |
557 (define_expand "vector_ngt<mode>" | |
558 [(set (match_operand:VEC_I 3 "vlogical_operand" "") | |
559 (gt:VEC_I (match_operand:VEC_I 1 "vlogical_operand" "") | |
560 (match_operand:VEC_I 2 "vlogical_operand" ""))) | |
561 (set (match_operand:VEC_I 0 "vlogical_operand" "") | |
562 (not:VEC_I (match_dup 3)))] | |
563 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
564 " | |
565 { | |
566 operands[3] = gen_reg_rtx_and_attrs (operands[0]); | |
567 }") | |
568 | |
569 (define_expand "vector_ngtu<mode>" | |
570 [(set (match_operand:VEC_I 3 "vlogical_operand" "") | |
571 (gtu:VEC_I (match_operand:VEC_I 1 "vlogical_operand" "") | |
572 (match_operand:VEC_I 2 "vlogical_operand" ""))) | |
573 (set (match_operand:VEC_I 0 "vlogical_operand" "") | |
574 (not:VEC_I (match_dup 3)))] | |
575 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
576 " | |
577 { | |
578 operands[3] = gen_reg_rtx_and_attrs (operands[0]); | |
579 }") | |
580 | |
581 (define_insn_and_split "*vector_uneq<mode>" | |
582 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
583 (uneq:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") | |
584 (match_operand:VEC_F 2 "vfloat_operand" "")))] | |
585 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
586 "#" | |
587 "" | |
588 [(set (match_dup 3) | |
589 (gt:VEC_F (match_dup 1) | |
590 (match_dup 2))) | |
591 (set (match_dup 4) | |
592 (gt:VEC_F (match_dup 2) | |
593 (match_dup 1))) | |
594 (set (match_dup 0) | |
595 (not:VEC_F (ior:VEC_F (match_dup 3) | |
596 (match_dup 4))))] | |
597 " | |
598 { | |
599 operands[3] = gen_reg_rtx (<MODE>mode); | |
600 operands[4] = gen_reg_rtx (<MODE>mode); | |
601 }") | |
602 | |
603 (define_insn_and_split "*vector_ltgt<mode>" | |
604 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
605 (ltgt:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") | |
606 (match_operand:VEC_F 2 "vfloat_operand" "")))] | |
607 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
608 "#" | |
609 "" | |
610 [(set (match_dup 3) | |
611 (gt:VEC_F (match_dup 1) | |
612 (match_dup 2))) | |
613 (set (match_dup 4) | |
614 (gt:VEC_F (match_dup 2) | |
615 (match_dup 1))) | |
616 (set (match_dup 0) | |
617 (ior:VEC_F (match_dup 3) | |
618 (match_dup 4)))] | |
619 " | |
620 { | |
621 operands[3] = gen_reg_rtx (<MODE>mode); | |
622 operands[4] = gen_reg_rtx (<MODE>mode); | |
623 }") | |
624 | |
625 (define_insn_and_split "*vector_ordered<mode>" | |
626 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
627 (ordered:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") | |
628 (match_operand:VEC_F 2 "vfloat_operand" "")))] | |
629 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
630 "#" | |
631 "" | |
632 [(set (match_dup 3) | |
633 (ge:VEC_F (match_dup 1) | |
634 (match_dup 2))) | |
635 (set (match_dup 4) | |
636 (ge:VEC_F (match_dup 2) | |
637 (match_dup 1))) | |
638 (set (match_dup 0) | |
639 (ior:VEC_F (match_dup 3) | |
640 (match_dup 4)))] | |
641 " | |
642 { | |
643 operands[3] = gen_reg_rtx (<MODE>mode); | |
644 operands[4] = gen_reg_rtx (<MODE>mode); | |
645 }") | |
646 | |
647 (define_insn_and_split "*vector_unordered<mode>" | |
648 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
649 (unordered:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") | |
650 (match_operand:VEC_F 2 "vfloat_operand" "")))] | |
651 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
652 "#" | |
653 "" | |
654 [(set (match_dup 3) | |
655 (ge:VEC_F (match_dup 1) | |
656 (match_dup 2))) | |
657 (set (match_dup 4) | |
658 (ge:VEC_F (match_dup 2) | |
659 (match_dup 1))) | |
660 (set (match_dup 0) | |
661 (and:VEC_F (not:VEC_F (match_dup 3)) | |
662 (not:VEC_F (match_dup 4))))] | |
663 " | |
664 { | |
665 operands[3] = gen_reg_rtx (<MODE>mode); | |
666 operands[4] = gen_reg_rtx (<MODE>mode); | |
667 }") | |
668 | |
669 ;; Note the arguments for __builtin_altivec_vsel are op2, op1, mask | |
670 ;; which is in the reverse order that we want | |
671 (define_expand "vector_select_<mode>" | |
672 [(set (match_operand:VEC_L 0 "vlogical_operand" "") | |
673 (if_then_else:VEC_L | |
674 (ne:CC (match_operand:VEC_L 3 "vlogical_operand" "") | |
675 (match_dup 4)) | |
676 (match_operand:VEC_L 2 "vlogical_operand" "") | |
677 (match_operand:VEC_L 1 "vlogical_operand" "")))] | |
678 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
679 "operands[4] = CONST0_RTX (<MODE>mode);") | |
680 | |
681 (define_expand "vector_select_<mode>_uns" | |
682 [(set (match_operand:VEC_L 0 "vlogical_operand" "") | |
683 (if_then_else:VEC_L | |
684 (ne:CCUNS (match_operand:VEC_L 3 "vlogical_operand" "") | |
685 (match_dup 4)) | |
686 (match_operand:VEC_L 2 "vlogical_operand" "") | |
687 (match_operand:VEC_L 1 "vlogical_operand" "")))] | |
688 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
689 "operands[4] = CONST0_RTX (<MODE>mode);") | |
690 | |
691 ;; Expansions that compare vectors producing a vector result and a predicate, | |
692 ;; setting CR6 to indicate a combined status | |
693 (define_expand "vector_eq_<mode>_p" | |
694 [(parallel | |
695 [(set (reg:CC CR6_REGNO) | |
696 (unspec:CC [(eq:CC (match_operand:VEC_A 1 "vlogical_operand" "") | |
697 (match_operand:VEC_A 2 "vlogical_operand" ""))] | |
698 UNSPEC_PREDICATE)) | |
699 (set (match_operand:VEC_A 0 "vlogical_operand" "") | |
700 (eq:VEC_A (match_dup 1) | |
701 (match_dup 2)))])] | |
702 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
703 "") | |
704 | |
705 ;; This expansion handles the V16QI, V8HI, and V4SI modes in the | |
706 ;; implementation of the vec_all_ne built-in functions on Power9. | |
707 (define_expand "vector_ne_<mode>_p" | |
708 [(parallel | |
709 [(set (reg:CC CR6_REGNO) | |
710 (unspec:CC [(ne:CC (match_operand:VI 1 "vlogical_operand") | |
711 (match_operand:VI 2 "vlogical_operand"))] | |
712 UNSPEC_PREDICATE)) | |
713 (set (match_dup 3) | |
714 (ne:VI (match_dup 1) | |
715 (match_dup 2)))]) | |
716 (set (match_operand:SI 0 "register_operand" "=r") | |
717 (lt:SI (reg:CC CR6_REGNO) | |
718 (const_int 0)))] | |
719 "TARGET_P9_VECTOR" | |
720 { | |
721 operands[3] = gen_reg_rtx (<MODE>mode); | |
722 }) | |
723 | |
724 ;; This expansion handles the V16QI, V8HI, and V4SI modes in the | |
725 ;; implementation of the vec_any_eq built-in functions on Power9. | |
726 (define_expand "vector_ae_<mode>_p" | |
727 [(parallel | |
728 [(set (reg:CC CR6_REGNO) | |
729 (unspec:CC [(ne:CC (match_operand:VI 1 "vlogical_operand") | |
730 (match_operand:VI 2 "vlogical_operand"))] | |
731 UNSPEC_PREDICATE)) | |
732 (set (match_dup 3) | |
733 (ne:VI (match_dup 1) | |
734 (match_dup 2)))]) | |
735 (set (match_operand:SI 0 "register_operand" "=r") | |
736 (lt:SI (reg:CC CR6_REGNO) | |
737 (const_int 0))) | |
738 (set (match_dup 0) | |
739 (xor:SI (match_dup 0) | |
740 (const_int 1)))] | |
741 "TARGET_P9_VECTOR" | |
742 { | |
743 operands[3] = gen_reg_rtx (<MODE>mode); | |
744 }) | |
745 | |
746 ;; This expansion handles the V16QI, V8HI, and V4SI modes in the | |
747 ;; implementation of the vec_all_nez and vec_any_eqz built-in | |
748 ;; functions on Power9. | |
749 (define_expand "vector_nez_<mode>_p" | |
750 [(parallel | |
751 [(set (reg:CC CR6_REGNO) | |
752 (unspec:CC [(unspec:VI | |
753 [(match_operand:VI 1 "vlogical_operand") | |
754 (match_operand:VI 2 "vlogical_operand")] | |
755 UNSPEC_NEZ_P)] | |
756 UNSPEC_PREDICATE)) | |
757 (set (match_operand:VI 0 "vlogical_operand") | |
758 (unspec:VI [(match_dup 1) | |
759 (match_dup 2)] | |
760 UNSPEC_NEZ_P))])] | |
761 "TARGET_P9_VECTOR" | |
762 "") | |
763 | |
764 ;; This expansion handles the V2DI mode in the implementation of the | |
765 ;; vec_all_ne built-in function on Power9. | |
766 ;; | |
767 ;; Since the Power9 "xvcmpne<mode>." instruction does not support DImode, | |
768 ;; this expands into the same rtl that would be used for the Power8 | |
769 ;; architecture. | |
770 (define_expand "vector_ne_v2di_p" | |
771 [(parallel | |
772 [(set (reg:CC CR6_REGNO) | |
773 (unspec:CC [(eq:CC (match_operand:V2DI 1 "vlogical_operand") | |
774 (match_operand:V2DI 2 "vlogical_operand"))] | |
775 UNSPEC_PREDICATE)) | |
776 (set (match_dup 3) | |
777 (eq:V2DI (match_dup 1) | |
778 (match_dup 2)))]) | |
779 (set (match_operand:SI 0 "register_operand" "=r") | |
780 (eq:SI (reg:CC CR6_REGNO) | |
781 (const_int 0)))] | |
782 "TARGET_P9_VECTOR" | |
783 { | |
784 operands[3] = gen_reg_rtx (V2DImode); | |
785 }) | |
786 | |
787 ;; This expansion handles the V2DI mode in the implementation of the | |
788 ;; vec_any_eq built-in function on Power9. | |
789 ;; | |
790 ;; Since the Power9 "xvcmpne<mode>." instruction does not support DImode, | |
791 ;; this expands into the same rtl that would be used for the Power8 | |
792 ;; architecture. | |
793 (define_expand "vector_ae_v2di_p" | |
794 [(parallel | |
795 [(set (reg:CC CR6_REGNO) | |
796 (unspec:CC [(eq:CC (match_operand:V2DI 1 "vlogical_operand") | |
797 (match_operand:V2DI 2 "vlogical_operand"))] | |
798 UNSPEC_PREDICATE)) | |
799 (set (match_dup 3) | |
800 (eq:V2DI (match_dup 1) | |
801 (match_dup 2)))]) | |
802 (set (match_operand:SI 0 "register_operand" "=r") | |
803 (eq:SI (reg:CC CR6_REGNO) | |
804 (const_int 0))) | |
805 (set (match_dup 0) | |
806 (xor:SI (match_dup 0) | |
807 (const_int 1)))] | |
808 "TARGET_P9_VECTOR" | |
809 { | |
810 operands[3] = gen_reg_rtx (V2DImode); | |
811 }) | |
812 | |
813 ;; This expansion handles the V4SF and V2DF modes in the Power9 | |
814 ;; implementation of the vec_all_ne built-in functions. Note that the | |
815 ;; expansions for this pattern with these modes makes no use of power9- | |
816 ;; specific instructions since there are no new power9 instructions | |
817 ;; for vector compare not equal with floating point arguments. | |
818 (define_expand "vector_ne_<mode>_p" | |
819 [(parallel | |
820 [(set (reg:CC CR6_REGNO) | |
821 (unspec:CC [(eq:CC (match_operand:VEC_F 1 "vlogical_operand") | |
822 (match_operand:VEC_F 2 "vlogical_operand"))] | |
823 UNSPEC_PREDICATE)) | |
824 (set (match_dup 3) | |
825 (eq:VEC_F (match_dup 1) | |
826 (match_dup 2)))]) | |
827 (set (match_operand:SI 0 "register_operand" "=r") | |
828 (eq:SI (reg:CC CR6_REGNO) | |
829 (const_int 0)))] | |
830 "TARGET_P9_VECTOR" | |
831 { | |
832 operands[3] = gen_reg_rtx (<MODE>mode); | |
833 }) | |
834 | |
835 ;; This expansion handles the V4SF and V2DF modes in the Power9 | |
836 ;; implementation of the vec_any_eq built-in functions. Note that the | |
837 ;; expansions for this pattern with these modes makes no use of power9- | |
838 ;; specific instructions since there are no new power9 instructions | |
839 ;; for vector compare not equal with floating point arguments. | |
840 (define_expand "vector_ae_<mode>_p" | |
841 [(parallel | |
842 [(set (reg:CC CR6_REGNO) | |
843 (unspec:CC [(eq:CC (match_operand:VEC_F 1 "vlogical_operand") | |
844 (match_operand:VEC_F 2 "vlogical_operand"))] | |
845 UNSPEC_PREDICATE)) | |
846 (set (match_dup 3) | |
847 (eq:VEC_F (match_dup 1) | |
848 (match_dup 2)))]) | |
849 (set (match_operand:SI 0 "register_operand" "=r") | |
850 (eq:SI (reg:CC CR6_REGNO) | |
851 (const_int 0))) | |
852 (set (match_dup 0) | |
853 (xor:SI (match_dup 0) | |
854 (const_int 1)))] | |
855 "TARGET_P9_VECTOR" | |
856 { | |
857 operands[3] = gen_reg_rtx (<MODE>mode); | |
858 }) | |
859 | |
860 (define_expand "vector_gt_<mode>_p" | |
861 [(parallel | |
862 [(set (reg:CC CR6_REGNO) | |
863 (unspec:CC [(gt:CC (match_operand:VEC_A 1 "vlogical_operand" "") | |
864 (match_operand:VEC_A 2 "vlogical_operand" ""))] | |
865 UNSPEC_PREDICATE)) | |
866 (set (match_operand:VEC_A 0 "vlogical_operand" "") | |
867 (gt:VEC_A (match_dup 1) | |
868 (match_dup 2)))])] | |
869 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
870 "") | |
871 | |
872 (define_expand "vector_ge_<mode>_p" | |
873 [(parallel | |
874 [(set (reg:CC CR6_REGNO) | |
875 (unspec:CC [(ge:CC (match_operand:VEC_F 1 "vfloat_operand" "") | |
876 (match_operand:VEC_F 2 "vfloat_operand" ""))] | |
877 UNSPEC_PREDICATE)) | |
878 (set (match_operand:VEC_F 0 "vfloat_operand" "") | |
879 (ge:VEC_F (match_dup 1) | |
880 (match_dup 2)))])] | |
881 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
882 "") | |
883 | |
884 (define_expand "vector_gtu_<mode>_p" | |
885 [(parallel | |
886 [(set (reg:CC CR6_REGNO) | |
887 (unspec:CC [(gtu:CC (match_operand:VEC_I 1 "vint_operand" "") | |
888 (match_operand:VEC_I 2 "vint_operand" ""))] | |
889 UNSPEC_PREDICATE)) | |
890 (set (match_operand:VEC_I 0 "vlogical_operand" "") | |
891 (gtu:VEC_I (match_dup 1) | |
892 (match_dup 2)))])] | |
893 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
894 "") | |
895 | |
896 ;; AltiVec/VSX predicates. | |
897 | |
898 ;; This expansion is triggered during expansion of predicate built-in | |
899 ;; functions (built-ins defined with the RS6000_BUILTIN_P macro) by the | |
900 ;; altivec_expand_predicate_builtin() function when the value of the | |
901 ;; integer constant first argument equals zero (aka __CR6_EQ in altivec.h). | |
902 (define_expand "cr6_test_for_zero" | |
903 [(set (match_operand:SI 0 "register_operand" "=r") | |
904 (eq:SI (reg:CC CR6_REGNO) | |
905 (const_int 0)))] | |
906 "TARGET_ALTIVEC || TARGET_VSX" | |
907 "") | |
908 | |
909 ;; This expansion is triggered during expansion of predicate built-in | |
910 ;; functions (built-ins defined with the RS6000_BUILTIN_P macro) by the | |
911 ;; altivec_expand_predicate_builtin() function when the value of the | |
912 ;; integer constant first argument equals one (aka __CR6_EQ_REV in altivec.h). | |
913 (define_expand "cr6_test_for_zero_reverse" | |
914 [(set (match_operand:SI 0 "register_operand" "=r") | |
915 (eq:SI (reg:CC CR6_REGNO) | |
916 (const_int 0))) | |
917 (set (match_dup 0) | |
918 (xor:SI (match_dup 0) | |
919 (const_int 1)))] | |
920 "TARGET_ALTIVEC || TARGET_VSX" | |
921 "") | |
922 | |
923 ;; This expansion is triggered during expansion of predicate built-in | |
924 ;; functions (built-ins defined with the RS6000_BUILTIN_P macro) by the | |
925 ;; altivec_expand_predicate_builtin() function when the value of the | |
926 ;; integer constant first argument equals two (aka __CR6_LT in altivec.h). | |
927 (define_expand "cr6_test_for_lt" | |
928 [(set (match_operand:SI 0 "register_operand" "=r") | |
929 (lt:SI (reg:CC CR6_REGNO) | |
930 (const_int 0)))] | |
931 "TARGET_ALTIVEC || TARGET_VSX" | |
932 "") | |
933 | |
934 ;; This expansion is triggered during expansion of predicate built-in | |
935 ;; functions (built-ins defined with the RS6000_BUILTIN_P macro) by the | |
936 ;; altivec_expand_predicate_builtin() function when the value of the | |
937 ;; integer constant first argument equals three | |
938 ;; (aka __CR6_LT_REV in altivec.h). | |
939 (define_expand "cr6_test_for_lt_reverse" | |
940 [(set (match_operand:SI 0 "register_operand" "=r") | |
941 (lt:SI (reg:CC CR6_REGNO) | |
942 (const_int 0))) | |
943 (set (match_dup 0) | |
944 (xor:SI (match_dup 0) | |
945 (const_int 1)))] | |
946 "TARGET_ALTIVEC || TARGET_VSX" | |
947 "") | |
948 | |
949 | |
950 ;; Vector count leading zeros | |
951 (define_expand "clz<mode>2" | |
952 [(set (match_operand:VEC_I 0 "register_operand" "") | |
953 (clz:VEC_I (match_operand:VEC_I 1 "register_operand" "")))] | |
954 "TARGET_P8_VECTOR") | |
955 | |
956 ;; Vector count trailing zeros | |
957 (define_expand "ctz<mode>2" | |
958 [(set (match_operand:VEC_I 0 "register_operand" "") | |
959 (ctz:VEC_I (match_operand:VEC_I 1 "register_operand" "")))] | |
960 "TARGET_P9_VECTOR") | |
961 | |
962 ;; Vector population count | |
963 (define_expand "popcount<mode>2" | |
964 [(set (match_operand:VEC_I 0 "register_operand" "") | |
965 (popcount:VEC_I (match_operand:VEC_I 1 "register_operand" "")))] | |
966 "TARGET_P8_VECTOR") | |
967 | |
968 ;; Vector parity | |
969 (define_expand "parity<mode>2" | |
970 [(set (match_operand:VEC_IP 0 "register_operand" "") | |
971 (parity:VEC_IP (match_operand:VEC_IP 1 "register_operand" "")))] | |
972 "TARGET_P9_VECTOR") | |
973 | |
974 | |
975 ;; Same size conversions | |
976 (define_expand "float<VEC_int><mode>2" | |
977 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
978 (float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand" "")))] | |
979 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
980 " | |
981 { | |
982 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) | |
983 { | |
984 emit_insn (gen_altivec_vcfsx (operands[0], operands[1], const0_rtx)); | |
985 DONE; | |
986 } | |
987 }") | |
988 | |
989 (define_expand "floatuns<VEC_int><mode>2" | |
990 [(set (match_operand:VEC_F 0 "vfloat_operand" "") | |
991 (unsigned_float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand" "")))] | |
992 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
993 " | |
994 { | |
995 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) | |
996 { | |
997 emit_insn (gen_altivec_vcfux (operands[0], operands[1], const0_rtx)); | |
998 DONE; | |
999 } | |
1000 }") | |
1001 | |
1002 (define_expand "fix_trunc<mode><VEC_int>2" | |
1003 [(set (match_operand:<VEC_INT> 0 "vint_operand" "") | |
1004 (fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand" "")))] | |
1005 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
1006 " | |
1007 { | |
1008 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) | |
1009 { | |
1010 emit_insn (gen_altivec_vctsxs (operands[0], operands[1], const0_rtx)); | |
1011 DONE; | |
1012 } | |
1013 }") | |
1014 | |
1015 (define_expand "fixuns_trunc<mode><VEC_int>2" | |
1016 [(set (match_operand:<VEC_INT> 0 "vint_operand" "") | |
1017 (unsigned_fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand" "")))] | |
1018 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
1019 " | |
1020 { | |
1021 if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) | |
1022 { | |
1023 emit_insn (gen_altivec_vctuxs (operands[0], operands[1], const0_rtx)); | |
1024 DONE; | |
1025 } | |
1026 }") | |
1027 | |
1028 | |
1029 ;; Vector initialization, set, extract | |
1030 (define_expand "vec_init<mode><VEC_base_l>" | |
1031 [(match_operand:VEC_E 0 "vlogical_operand" "") | |
1032 (match_operand:VEC_E 1 "" "")] | |
1033 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
1034 { | |
1035 rs6000_expand_vector_init (operands[0], operands[1]); | |
1036 DONE; | |
1037 }) | |
1038 | |
1039 (define_expand "vec_set<mode>" | |
1040 [(match_operand:VEC_E 0 "vlogical_operand" "") | |
1041 (match_operand:<VEC_base> 1 "register_operand" "") | |
1042 (match_operand 2 "const_int_operand" "")] | |
1043 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
1044 { | |
1045 rs6000_expand_vector_set (operands[0], operands[1], INTVAL (operands[2])); | |
1046 DONE; | |
1047 }) | |
1048 | |
1049 (define_expand "vec_extract<mode><VEC_base_l>" | |
1050 [(match_operand:<VEC_base> 0 "register_operand" "") | |
1051 (match_operand:VEC_E 1 "vlogical_operand" "") | |
1052 (match_operand 2 "const_int_operand" "")] | |
1053 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
1054 { | |
1055 rs6000_expand_vector_extract (operands[0], operands[1], operands[2]); | |
1056 DONE; | |
1057 }) | |
1058 | |
1059 ;; Convert double word types to single word types | |
1060 (define_expand "vec_pack_trunc_v2df" | |
1061 [(match_operand:V4SF 0 "vfloat_operand" "") | |
1062 (match_operand:V2DF 1 "vfloat_operand" "") | |
1063 (match_operand:V2DF 2 "vfloat_operand" "")] | |
1064 "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" | |
1065 { | |
1066 rtx r1 = gen_reg_rtx (V4SFmode); | |
1067 rtx r2 = gen_reg_rtx (V4SFmode); | |
1068 | |
1069 emit_insn (gen_vsx_xvcvdpsp (r1, operands[1])); | |
1070 emit_insn (gen_vsx_xvcvdpsp (r2, operands[2])); | |
1071 rs6000_expand_extract_even (operands[0], r1, r2); | |
1072 DONE; | |
1073 }) | |
1074 | |
1075 (define_expand "vec_pack_sfix_trunc_v2df" | |
1076 [(match_operand:V4SI 0 "vint_operand" "") | |
1077 (match_operand:V2DF 1 "vfloat_operand" "") | |
1078 (match_operand:V2DF 2 "vfloat_operand" "")] | |
1079 "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" | |
1080 { | |
1081 rtx r1 = gen_reg_rtx (V4SImode); | |
1082 rtx r2 = gen_reg_rtx (V4SImode); | |
1083 | |
1084 emit_insn (gen_vsx_xvcvdpsxws (r1, operands[1])); | |
1085 emit_insn (gen_vsx_xvcvdpsxws (r2, operands[2])); | |
1086 rs6000_expand_extract_even (operands[0], r1, r2); | |
1087 DONE; | |
1088 }) | |
1089 | |
1090 (define_expand "vec_pack_ufix_trunc_v2df" | |
1091 [(match_operand:V4SI 0 "vint_operand" "") | |
1092 (match_operand:V2DF 1 "vfloat_operand" "") | |
1093 (match_operand:V2DF 2 "vfloat_operand" "")] | |
1094 "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" | |
1095 { | |
1096 rtx r1 = gen_reg_rtx (V4SImode); | |
1097 rtx r2 = gen_reg_rtx (V4SImode); | |
1098 | |
1099 emit_insn (gen_vsx_xvcvdpuxws (r1, operands[1])); | |
1100 emit_insn (gen_vsx_xvcvdpuxws (r2, operands[2])); | |
1101 rs6000_expand_extract_even (operands[0], r1, r2); | |
1102 DONE; | |
1103 }) | |
1104 | |
1105 ;; Convert single word types to double word | |
1106 (define_expand "vec_unpacks_hi_v4sf" | |
1107 [(match_operand:V2DF 0 "vfloat_operand" "") | |
1108 (match_operand:V4SF 1 "vfloat_operand" "")] | |
1109 "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" | |
1110 { | |
1111 rtx reg = gen_reg_rtx (V4SFmode); | |
1112 | |
1113 rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN); | |
1114 emit_insn (gen_vsx_xvcvspdp (operands[0], reg)); | |
1115 DONE; | |
1116 }) | |
1117 | |
1118 (define_expand "vec_unpacks_lo_v4sf" | |
1119 [(match_operand:V2DF 0 "vfloat_operand" "") | |
1120 (match_operand:V4SF 1 "vfloat_operand" "")] | |
1121 "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" | |
1122 { | |
1123 rtx reg = gen_reg_rtx (V4SFmode); | |
1124 | |
1125 rs6000_expand_interleave (reg, operands[1], operands[1], !BYTES_BIG_ENDIAN); | |
1126 emit_insn (gen_vsx_xvcvspdp (operands[0], reg)); | |
1127 DONE; | |
1128 }) | |
1129 | |
1130 (define_expand "vec_unpacks_float_hi_v4si" | |
1131 [(match_operand:V2DF 0 "vfloat_operand" "") | |
1132 (match_operand:V4SI 1 "vint_operand" "")] | |
1133 "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" | |
1134 { | |
1135 rtx reg = gen_reg_rtx (V4SImode); | |
1136 | |
1137 rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN); | |
1138 emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg)); | |
1139 DONE; | |
1140 }) | |
1141 | |
1142 (define_expand "vec_unpacks_float_lo_v4si" | |
1143 [(match_operand:V2DF 0 "vfloat_operand" "") | |
1144 (match_operand:V4SI 1 "vint_operand" "")] | |
1145 "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" | |
1146 { | |
1147 rtx reg = gen_reg_rtx (V4SImode); | |
1148 | |
1149 rs6000_expand_interleave (reg, operands[1], operands[1], !BYTES_BIG_ENDIAN); | |
1150 emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg)); | |
1151 DONE; | |
1152 }) | |
1153 | |
1154 (define_expand "vec_unpacku_float_hi_v4si" | |
1155 [(match_operand:V2DF 0 "vfloat_operand" "") | |
1156 (match_operand:V4SI 1 "vint_operand" "")] | |
1157 "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" | |
1158 { | |
1159 rtx reg = gen_reg_rtx (V4SImode); | |
1160 | |
1161 rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN); | |
1162 emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg)); | |
1163 DONE; | |
1164 }) | |
1165 | |
1166 (define_expand "vec_unpacku_float_lo_v4si" | |
1167 [(match_operand:V2DF 0 "vfloat_operand" "") | |
1168 (match_operand:V4SI 1 "vint_operand" "")] | |
1169 "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" | |
1170 { | |
1171 rtx reg = gen_reg_rtx (V4SImode); | |
1172 | |
1173 rs6000_expand_interleave (reg, operands[1], operands[1], !BYTES_BIG_ENDIAN); | |
1174 emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg)); | |
1175 DONE; | |
1176 }) | |
1177 | |
1178 | |
1179 ;; Align vector loads with a permute. | |
1180 (define_expand "vec_realign_load_<mode>" | |
1181 [(match_operand:VEC_K 0 "vlogical_operand" "") | |
1182 (match_operand:VEC_K 1 "vlogical_operand" "") | |
1183 (match_operand:VEC_K 2 "vlogical_operand" "") | |
1184 (match_operand:V16QI 3 "vlogical_operand" "")] | |
1185 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
1186 { | |
1187 if (BYTES_BIG_ENDIAN) | |
1188 emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1], | |
1189 operands[2], operands[3])); | |
1190 else | |
1191 { | |
1192 /* We have changed lvsr to lvsl, so to complete the transformation | |
1193 of vperm for LE, we must swap the inputs. */ | |
1194 rtx unspec = gen_rtx_UNSPEC (<MODE>mode, | |
1195 gen_rtvec (3, operands[2], | |
1196 operands[1], operands[3]), | |
1197 UNSPEC_VPERM); | |
1198 emit_move_insn (operands[0], unspec); | |
1199 } | |
1200 DONE; | |
1201 }) | |
1202 | |
1203 ;; Under VSX, vectors of 4/8 byte alignments do not need to be aligned | |
1204 ;; since the load already handles it. | |
1205 (define_expand "movmisalign<mode>" | |
1206 [(set (match_operand:VEC_N 0 "nonimmediate_operand" "") | |
1207 (match_operand:VEC_N 1 "any_operand" ""))] | |
1208 "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_ALLOW_MOVMISALIGN" | |
1209 "") | |
1210 | |
1211 ;; Vector shift right in bits. Currently supported ony for shift | |
1212 ;; amounts that can be expressed as byte shifts (divisible by 8). | |
1213 ;; General shift amounts can be supported using vsro + vsr. We're | |
1214 ;; not expecting to see these yet (the vectorizer currently | |
1215 ;; generates only shifts by a whole number of vector elements). | |
1216 ;; Note that the vec_shr operation is actually defined as | |
1217 ;; 'shift toward element 0' so is a shr for LE and shl for BE. | |
1218 (define_expand "vec_shr_<mode>" | |
1219 [(match_operand:VEC_L 0 "vlogical_operand" "") | |
1220 (match_operand:VEC_L 1 "vlogical_operand" "") | |
1221 (match_operand:QI 2 "reg_or_short_operand" "")] | |
1222 "TARGET_ALTIVEC" | |
1223 " | |
1224 { | |
1225 rtx bitshift = operands[2]; | |
1226 rtx shift; | |
1227 rtx insn; | |
1228 rtx zero_reg, op1, op2; | |
1229 HOST_WIDE_INT bitshift_val; | |
1230 HOST_WIDE_INT byteshift_val; | |
1231 | |
1232 if (! CONSTANT_P (bitshift)) | |
1233 FAIL; | |
1234 bitshift_val = INTVAL (bitshift); | |
1235 if (bitshift_val & 0x7) | |
1236 FAIL; | |
1237 byteshift_val = (bitshift_val >> 3); | |
1238 zero_reg = gen_reg_rtx (<MODE>mode); | |
1239 emit_move_insn (zero_reg, CONST0_RTX (<MODE>mode)); | |
1240 if (!BYTES_BIG_ENDIAN) | |
1241 { | |
1242 byteshift_val = 16 - byteshift_val; | |
1243 op1 = zero_reg; | |
1244 op2 = operands[1]; | |
1245 } | |
1246 else | |
1247 { | |
1248 op1 = operands[1]; | |
1249 op2 = zero_reg; | |
1250 } | |
1251 | |
1252 if (TARGET_VSX && (byteshift_val & 0x3) == 0) | |
1253 { | |
1254 shift = gen_rtx_CONST_INT (QImode, byteshift_val >> 2); | |
1255 insn = gen_vsx_xxsldwi_<mode> (operands[0], op1, op2, shift); | |
1256 } | |
1257 else | |
1258 { | |
1259 shift = gen_rtx_CONST_INT (QImode, byteshift_val); | |
1260 insn = gen_altivec_vsldoi_<mode> (operands[0], op1, op2, shift); | |
1261 } | |
1262 | |
1263 emit_insn (insn); | |
1264 DONE; | |
1265 }") | |
1266 | |
1267 ;; Expanders for rotate each element in a vector | |
1268 (define_expand "vrotl<mode>3" | |
1269 [(set (match_operand:VEC_I 0 "vint_operand" "") | |
1270 (rotate:VEC_I (match_operand:VEC_I 1 "vint_operand" "") | |
1271 (match_operand:VEC_I 2 "vint_operand" "")))] | |
1272 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
1273 "") | |
1274 | |
1275 ;; Expanders for arithmetic shift left on each vector element | |
1276 (define_expand "vashl<mode>3" | |
1277 [(set (match_operand:VEC_I 0 "vint_operand" "") | |
1278 (ashift:VEC_I (match_operand:VEC_I 1 "vint_operand" "") | |
1279 (match_operand:VEC_I 2 "vint_operand" "")))] | |
1280 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
1281 "") | |
1282 | |
1283 ;; Expanders for logical shift right on each vector element | |
1284 (define_expand "vlshr<mode>3" | |
1285 [(set (match_operand:VEC_I 0 "vint_operand" "") | |
1286 (lshiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand" "") | |
1287 (match_operand:VEC_I 2 "vint_operand" "")))] | |
1288 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
1289 "") | |
1290 | |
1291 ;; Expanders for arithmetic shift right on each vector element | |
1292 (define_expand "vashr<mode>3" | |
1293 [(set (match_operand:VEC_I 0 "vint_operand" "") | |
1294 (ashiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand" "") | |
1295 (match_operand:VEC_I 2 "vint_operand" "")))] | |
1296 "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" | |
1297 "") | |
1298 | |
1299 ;; Vector reduction expanders for VSX | |
1300 ; The (VEC_reduc:... | |
1301 ; (op1) | |
1302 ; (unspec:... [(const_int 0)] UNSPEC_REDUC)) | |
1303 ; | |
1304 ; is to allow us to use a code iterator, but not completely list all of the | |
1305 ; vector rotates, etc. to prevent canonicalization | |
1306 | |
1307 | |
1308 (define_expand "reduc_<VEC_reduc:VEC_reduc_name>_scal_<VEC_F:mode>" | |
1309 [(match_operand:<VEC_base> 0 "register_operand" "") | |
1310 (VEC_reduc:VEC_F (match_operand:VEC_F 1 "vfloat_operand" "") | |
1311 (unspec:VEC_F [(const_int 0)] UNSPEC_REDUC))] | |
1312 "VECTOR_UNIT_VSX_P (<VEC_F:MODE>mode)" | |
1313 { | |
1314 rtx vec = gen_reg_rtx (<VEC_F:MODE>mode); | |
1315 rtx elt = BYTES_BIG_ENDIAN | |
1316 ? gen_int_mode (GET_MODE_NUNITS (<VEC_F:MODE>mode) - 1, QImode) | |
1317 : const0_rtx; | |
1318 emit_insn (gen_vsx_reduc_<VEC_reduc:VEC_reduc_name>_<VEC_F:mode> (vec, | |
1319 operand1)); | |
1320 emit_insn (gen_vsx_extract_<VEC_F:mode> (operand0, vec, elt)); | |
1321 DONE; | |
1322 }) | |
1323 | |
1324 | |
1325 ;;; Expanders for vector insn patterns shared between the SPE and TARGET_PAIRED systems. | |
1326 | |
1327 (define_expand "absv2sf2" | |
1328 [(set (match_operand:V2SF 0 "gpc_reg_operand" "") | |
1329 (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")))] | |
1330 "TARGET_PAIRED_FLOAT || TARGET_SPE" | |
1331 "") | |
1332 | |
1333 (define_expand "negv2sf2" | |
1334 [(set (match_operand:V2SF 0 "gpc_reg_operand" "") | |
1335 (neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "")))] | |
1336 "TARGET_PAIRED_FLOAT || TARGET_SPE" | |
1337 "") | |
1338 | |
1339 (define_expand "addv2sf3" | |
1340 [(set (match_operand:V2SF 0 "gpc_reg_operand" "") | |
1341 (plus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "") | |
1342 (match_operand:V2SF 2 "gpc_reg_operand" "")))] | |
1343 "TARGET_PAIRED_FLOAT || TARGET_SPE" | |
1344 " | |
1345 { | |
1346 if (TARGET_SPE) | |
1347 { | |
1348 /* We need to make a note that we clobber SPEFSCR. */ | |
1349 rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); | |
1350 | |
1351 XVECEXP (par, 0, 0) = gen_rtx_SET (operands[0], | |
1352 gen_rtx_PLUS (V2SFmode, operands[1], operands[2])); | |
1353 XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO)); | |
1354 emit_insn (par); | |
1355 DONE; | |
1356 } | |
1357 }") | |
1358 | |
1359 (define_expand "subv2sf3" | |
1360 [(set (match_operand:V2SF 0 "gpc_reg_operand" "") | |
1361 (minus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "") | |
1362 (match_operand:V2SF 2 "gpc_reg_operand" "")))] | |
1363 "TARGET_PAIRED_FLOAT || TARGET_SPE" | |
1364 " | |
1365 { | |
1366 if (TARGET_SPE) | |
1367 { | |
1368 /* We need to make a note that we clobber SPEFSCR. */ | |
1369 rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); | |
1370 | |
1371 XVECEXP (par, 0, 0) = gen_rtx_SET (operands[0], | |
1372 gen_rtx_MINUS (V2SFmode, operands[1], operands[2])); | |
1373 XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO)); | |
1374 emit_insn (par); | |
1375 DONE; | |
1376 } | |
1377 }") | |
1378 | |
1379 (define_expand "mulv2sf3" | |
1380 [(set (match_operand:V2SF 0 "gpc_reg_operand" "") | |
1381 (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "") | |
1382 (match_operand:V2SF 2 "gpc_reg_operand" "")))] | |
1383 "TARGET_PAIRED_FLOAT || TARGET_SPE" | |
1384 " | |
1385 { | |
1386 if (TARGET_SPE) | |
1387 { | |
1388 /* We need to make a note that we clobber SPEFSCR. */ | |
1389 rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); | |
1390 | |
1391 XVECEXP (par, 0, 0) = gen_rtx_SET (operands[0], | |
1392 gen_rtx_MULT (V2SFmode, operands[1], operands[2])); | |
1393 XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO)); | |
1394 emit_insn (par); | |
1395 DONE; | |
1396 } | |
1397 }") | |
1398 | |
1399 (define_expand "divv2sf3" | |
1400 [(set (match_operand:V2SF 0 "gpc_reg_operand" "") | |
1401 (div:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "") | |
1402 (match_operand:V2SF 2 "gpc_reg_operand" "")))] | |
1403 "TARGET_PAIRED_FLOAT || TARGET_SPE" | |
1404 " | |
1405 { | |
1406 if (TARGET_SPE) | |
1407 { | |
1408 /* We need to make a note that we clobber SPEFSCR. */ | |
1409 rtx par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); | |
1410 | |
1411 XVECEXP (par, 0, 0) = gen_rtx_SET (operands[0], | |
1412 gen_rtx_DIV (V2SFmode, operands[1], operands[2])); | |
1413 XVECEXP (par, 0, 1) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, SPEFSCR_REGNO)); | |
1414 emit_insn (par); | |
1415 DONE; | |
1416 } | |
1417 }") |