comparison gcc/config/rs6000/vector.md @ 111:04ced10e8804

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