1 1.1 mrg ;; Expander definitions for vector support between altivec & vsx. No 2 1.1 mrg ;; instructions are in this file, this file provides the generic vector 3 1.1 mrg ;; expander, and the actual vector instructions will be in altivec.md and 4 1.1 mrg ;; vsx.md 5 1.1 mrg 6 1.14 mrg ;; Copyright (C) 2009-2022 Free Software Foundation, Inc. 7 1.1 mrg ;; Contributed by Michael Meissner <meissner (a] linux.vnet.ibm.com> 8 1.1 mrg 9 1.1 mrg ;; This file is part of GCC. 10 1.1 mrg 11 1.1 mrg ;; GCC is free software; you can redistribute it and/or modify it 12 1.1 mrg ;; under the terms of the GNU General Public License as published 13 1.1 mrg ;; by the Free Software Foundation; either version 3, or (at your 14 1.1 mrg ;; option) any later version. 15 1.1 mrg 16 1.1 mrg ;; GCC is distributed in the hope that it will be useful, but WITHOUT 17 1.1 mrg ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 1.1 mrg ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 1.1 mrg ;; License for more details. 20 1.1 mrg 21 1.1 mrg ;; You should have received a copy of the GNU General Public License 22 1.1 mrg ;; along with GCC; see the file COPYING3. If not see 23 1.1 mrg ;; <http://www.gnu.org/licenses/>. 24 1.1 mrg 25 1.1 mrg 26 1.1 mrg ;; Vector int modes 27 1.3 mrg (define_mode_iterator VEC_I [V16QI V8HI V4SI V2DI]) 28 1.1 mrg 29 1.14 mrg ;; 128-bit int modes 30 1.14 mrg (define_mode_iterator VEC_TI [V1TI TI]) 31 1.14 mrg 32 1.7 mrg ;; Vector int modes for parity 33 1.7 mrg (define_mode_iterator VEC_IP [V8HI 34 1.7 mrg V4SI 35 1.7 mrg V2DI 36 1.7 mrg V1TI 37 1.10 mrg TI]) 38 1.7 mrg 39 1.1 mrg ;; Vector float modes 40 1.1 mrg (define_mode_iterator VEC_F [V4SF V2DF]) 41 1.1 mrg 42 1.1 mrg ;; Vector arithmetic modes 43 1.3 mrg (define_mode_iterator VEC_A [V16QI V8HI V4SI V2DI V4SF V2DF]) 44 1.1 mrg 45 1.1 mrg ;; Vector modes that need alginment via permutes 46 1.1 mrg (define_mode_iterator VEC_K [V16QI V8HI V4SI V4SF]) 47 1.1 mrg 48 1.1 mrg ;; Vector logical modes 49 1.7 mrg (define_mode_iterator VEC_L [V16QI V8HI V4SI V2DI V4SF V2DF V1TI TI KF TF]) 50 1.1 mrg 51 1.7 mrg ;; Vector modes for moves. Don't do TImode or TFmode here, since their 52 1.7 mrg ;; moves are handled elsewhere. 53 1.7 mrg (define_mode_iterator VEC_M [V16QI V8HI V4SI V2DI V4SF V2DF V1TI KF]) 54 1.1 mrg 55 1.1 mrg ;; Vector modes for types that don't need a realignment under VSX 56 1.7 mrg (define_mode_iterator VEC_N [V4SI V4SF V2DI V2DF V1TI KF TF]) 57 1.1 mrg 58 1.1 mrg ;; Vector comparison modes 59 1.14 mrg (define_mode_iterator VEC_C [V16QI V8HI V4SI V2DI V4SF V2DF V1TI]) 60 1.1 mrg 61 1.1 mrg ;; Vector init/extract modes 62 1.1 mrg (define_mode_iterator VEC_E [V16QI V8HI V4SI V2DI V4SF V2DF]) 63 1.1 mrg 64 1.1 mrg ;; Vector modes for 64-bit base types 65 1.1 mrg (define_mode_iterator VEC_64 [V2DI V2DF]) 66 1.1 mrg 67 1.9 mrg ;; Vector integer modes 68 1.9 mrg (define_mode_iterator VI [V4SI V8HI V16QI]) 69 1.9 mrg 70 1.1 mrg ;; Base type from vector mode 71 1.1 mrg (define_mode_attr VEC_base [(V16QI "QI") 72 1.1 mrg (V8HI "HI") 73 1.1 mrg (V4SI "SI") 74 1.1 mrg (V2DI "DI") 75 1.1 mrg (V4SF "SF") 76 1.1 mrg (V2DF "DF") 77 1.3 mrg (V1TI "TI") 78 1.1 mrg (TI "TI")]) 79 1.1 mrg 80 1.10 mrg ;; As above, but in lower case 81 1.10 mrg (define_mode_attr VEC_base_l [(V16QI "qi") 82 1.10 mrg (V8HI "hi") 83 1.10 mrg (V4SI "si") 84 1.10 mrg (V2DI "di") 85 1.10 mrg (V4SF "sf") 86 1.10 mrg (V2DF "df") 87 1.10 mrg (V1TI "ti") 88 1.10 mrg (TI "ti")]) 89 1.10 mrg 90 1.1 mrg ;; Same size integer type for floating point data 91 1.1 mrg (define_mode_attr VEC_int [(V4SF "v4si") 92 1.1 mrg (V2DF "v2di")]) 93 1.1 mrg 94 1.1 mrg (define_mode_attr VEC_INT [(V4SF "V4SI") 95 1.1 mrg (V2DF "V2DI")]) 96 1.1 mrg 97 1.1 mrg ;; constants for unspec 98 1.3 mrg (define_c_enum "unspec" [UNSPEC_PREDICATE 99 1.9 mrg UNSPEC_REDUC 100 1.9 mrg UNSPEC_NEZ_P]) 101 1.3 mrg 102 1.3 mrg ;; Vector reduction code iterators 103 1.3 mrg (define_code_iterator VEC_reduc [plus smin smax]) 104 1.3 mrg 105 1.7 mrg (define_code_attr VEC_reduc_name [(plus "plus") 106 1.3 mrg (smin "smin") 107 1.3 mrg (smax "smax")]) 108 1.3 mrg 109 1.3 mrg (define_code_attr VEC_reduc_rtx [(plus "add") 110 1.3 mrg (smin "smin") 111 1.3 mrg (smax "smax")]) 112 1.1 mrg 113 1.12 mrg ;; code iterators and attributes for vector FP comparison operators: 114 1.12 mrg (define_code_iterator 115 1.12 mrg vector_fp_comparison_simple [lt le ne ungt unge unlt unle]) 116 1.12 mrg (define_code_iterator 117 1.12 mrg vector_fp_comparison_complex [ltgt uneq unordered ordered]) 118 1.12 mrg 119 1.1 mrg 121 1.3 mrg ;; Vector move instructions. Little-endian VSX loads and stores require 122 1.1 mrg ;; special handling to circumvent "element endianness." 123 1.10 mrg (define_expand "mov<mode>" 124 1.10 mrg [(set (match_operand:VEC_M 0 "nonimmediate_operand") 125 1.1 mrg (match_operand:VEC_M 1 "any_operand"))] 126 1.1 mrg "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" 127 1.1 mrg { 128 1.1 mrg if (can_create_pseudo_p ()) 129 1.7 mrg { 130 1.7 mrg if (CONSTANT_P (operands[1])) 131 1.7 mrg { 132 1.7 mrg if (FLOAT128_VECTOR_P (<MODE>mode)) 133 1.7 mrg { 134 1.7 mrg if (!easy_fp_constant (operands[1], <MODE>mode)) 135 1.7 mrg operands[1] = force_const_mem (<MODE>mode, operands[1]); 136 1.7 mrg } 137 1.7 mrg else if (!easy_vector_constant (operands[1], <MODE>mode)) 138 1.7 mrg operands[1] = force_const_mem (<MODE>mode, operands[1]); 139 1.1 mrg } 140 1.7 mrg 141 1.7 mrg if (!vlogical_operand (operands[0], <MODE>mode) 142 1.1 mrg && !vlogical_operand (operands[1], <MODE>mode)) 143 1.1 mrg operands[1] = force_reg (<MODE>mode, operands[1]); 144 1.10 mrg } 145 1.10 mrg /* When generating load/store instructions to/from VSX registers on 146 1.10 mrg pre-power9 hardware in little endian mode, we need to emit register 147 1.10 mrg permute instructions to byte swap the contents, since the VSX load/store 148 1.10 mrg instructions do not include a byte swap as part of their operation. 149 1.3 mrg Altivec loads and stores have no such problem, so we skip them below. */ 150 1.3 mrg if (!BYTES_BIG_ENDIAN 151 1.7 mrg && VECTOR_MEM_VSX_P (<MODE>mode) 152 1.3 mrg && !TARGET_P9_VECTOR 153 1.10 mrg && !gpr_or_gpr_p (operands[0], operands[1]) 154 1.10 mrg && ((memory_operand (operands[0], <MODE>mode) 155 1.10 mrg && !altivec_indexed_or_indirect_operand(operands[0], <MODE>mode)) 156 1.10 mrg ^ (memory_operand (operands[1], <MODE>mode) 157 1.3 mrg && !altivec_indexed_or_indirect_operand(operands[1], <MODE>mode)))) 158 1.3 mrg { 159 1.3 mrg rs6000_emit_le_vsx_move (operands[0], operands[1], <MODE>mode); 160 1.3 mrg DONE; 161 1.1 mrg } 162 1.1 mrg }) 163 1.1 mrg 164 1.1 mrg ;; Generic vector floating point load/store instructions. These will match 165 1.1 mrg ;; insns defined in vsx.md or altivec.md depending on the switches. 166 1.10 mrg (define_expand "vector_load_<mode>" 167 1.10 mrg [(set (match_operand:VEC_M 0 "vfloat_operand") 168 1.1 mrg (match_operand:VEC_M 1 "memory_operand"))] 169 1.1 mrg "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" 170 1.1 mrg "") 171 1.1 mrg 172 1.10 mrg (define_expand "vector_store_<mode>" 173 1.10 mrg [(set (match_operand:VEC_M 0 "memory_operand") 174 1.1 mrg (match_operand:VEC_M 1 "vfloat_operand"))] 175 1.1 mrg "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" 176 1.1 mrg "") 177 1.1 mrg 178 1.1 mrg ;; Splits if a GPR register was chosen for the move 179 1.10 mrg (define_split 180 1.10 mrg [(set (match_operand:VEC_L 0 "nonimmediate_operand") 181 1.1 mrg (match_operand:VEC_L 1 "input_operand"))] 182 1.1 mrg "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode) 183 1.3 mrg && reload_completed 184 1.3 mrg && gpr_or_gpr_p (operands[0], operands[1]) 185 1.3 mrg && !direct_move_p (operands[0], operands[1]) 186 1.1 mrg && !quad_load_store_p (operands[0], operands[1])" 187 1.1 mrg [(pc)] 188 1.1 mrg { 189 1.1 mrg rs6000_split_multireg_move (operands[0], operands[1]); 190 1.1 mrg DONE; 191 1.1 mrg }) 192 1.1 mrg 193 1.1 mrg 195 1.10 mrg ;; Generic floating point vector arithmetic support 196 1.10 mrg (define_expand "add<mode>3" 197 1.10 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 198 1.1 mrg (plus:VEC_F (match_operand:VEC_F 1 "vfloat_operand") 199 1.1 mrg (match_operand:VEC_F 2 "vfloat_operand")))] 200 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 201 1.1 mrg "") 202 1.10 mrg 203 1.10 mrg (define_expand "sub<mode>3" 204 1.10 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 205 1.1 mrg (minus:VEC_F (match_operand:VEC_F 1 "vfloat_operand") 206 1.1 mrg (match_operand:VEC_F 2 "vfloat_operand")))] 207 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 208 1.1 mrg "") 209 1.10 mrg 210 1.10 mrg (define_expand "mul<mode>3" 211 1.10 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 212 1.3 mrg (mult:VEC_F (match_operand:VEC_F 1 "vfloat_operand") 213 1.1 mrg (match_operand:VEC_F 2 "vfloat_operand")))] 214 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 215 1.1 mrg { 216 1.1 mrg if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) 217 1.1 mrg { 218 1.1 mrg emit_insn (gen_altivec_mulv4sf3 (operands[0], operands[1], operands[2])); 219 1.3 mrg DONE; 220 1.1 mrg } 221 1.1 mrg }) 222 1.10 mrg 223 1.10 mrg (define_expand "div<mode>3" 224 1.10 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 225 1.1 mrg (div:VEC_F (match_operand:VEC_F 1 "vfloat_operand") 226 1.9 mrg (match_operand:VEC_F 2 "vfloat_operand")))] 227 1.9 mrg "VECTOR_UNIT_VSX_P (<MODE>mode)" 228 1.9 mrg { 229 1.9 mrg if (RS6000_RECIP_AUTO_RE_P (<MODE>mode) 230 1.9 mrg && can_create_pseudo_p () && flag_finite_math_only 231 1.9 mrg && !flag_trapping_math && flag_reciprocal_math) 232 1.9 mrg { 233 1.9 mrg rs6000_emit_swdiv (operands[0], operands[1], operands[2], true); 234 1.9 mrg DONE; 235 1.1 mrg } 236 1.1 mrg }) 237 1.10 mrg 238 1.10 mrg (define_expand "neg<mode>2" 239 1.1 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 240 1.1 mrg (neg:VEC_F (match_operand:VEC_F 1 "vfloat_operand")))] 241 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 242 1.1 mrg { 243 1.1 mrg if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) 244 1.1 mrg { 245 1.1 mrg emit_insn (gen_altivec_negv4sf2 (operands[0], operands[1])); 246 1.10 mrg DONE; 247 1.1 mrg } 248 1.1 mrg }) 249 1.10 mrg 250 1.10 mrg (define_expand "abs<mode>2" 251 1.1 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 252 1.1 mrg (abs:VEC_F (match_operand:VEC_F 1 "vfloat_operand")))] 253 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 254 1.1 mrg { 255 1.1 mrg if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) 256 1.1 mrg { 257 1.1 mrg emit_insn (gen_altivec_absv4sf2 (operands[0], operands[1])); 258 1.10 mrg DONE; 259 1.1 mrg } 260 1.1 mrg }) 261 1.10 mrg 262 1.10 mrg (define_expand "smin<mode>3" 263 1.10 mrg [(set (match_operand:VEC_F 0 "register_operand") 264 1.1 mrg (smin:VEC_F (match_operand:VEC_F 1 "register_operand") 265 1.1 mrg (match_operand:VEC_F 2 "register_operand")))] 266 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 267 1.1 mrg "") 268 1.10 mrg 269 1.10 mrg (define_expand "smax<mode>3" 270 1.10 mrg [(set (match_operand:VEC_F 0 "register_operand") 271 1.1 mrg (smax:VEC_F (match_operand:VEC_F 1 "register_operand") 272 1.1 mrg (match_operand:VEC_F 2 "register_operand")))] 273 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 274 1.1 mrg "") 275 1.1 mrg 276 1.10 mrg 277 1.10 mrg (define_expand "sqrt<mode>2" 278 1.1 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 279 1.7 mrg (sqrt:VEC_F (match_operand:VEC_F 1 "vfloat_operand")))] 280 1.7 mrg "VECTOR_UNIT_VSX_P (<MODE>mode)" 281 1.7 mrg { 282 1.7 mrg if (<MODE>mode == V4SFmode 283 1.7 mrg && !optimize_function_for_size_p (cfun) 284 1.7 mrg && flag_finite_math_only && !flag_trapping_math 285 1.7 mrg && flag_unsafe_math_optimizations) 286 1.7 mrg { 287 1.7 mrg rs6000_emit_swsqrt (operands[0], operands[1], 0); 288 1.7 mrg DONE; 289 1.1 mrg } 290 1.3 mrg }) 291 1.10 mrg 292 1.10 mrg (define_expand "rsqrte<mode>2" 293 1.3 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 294 1.3 mrg (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand")] 295 1.3 mrg UNSPEC_RSQRT))] 296 1.3 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 297 1.3 mrg "") 298 1.10 mrg 299 1.10 mrg (define_expand "re<mode>2" 300 1.3 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 301 1.3 mrg (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand")] 302 1.3 mrg UNSPEC_FRES))] 303 1.3 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 304 1.1 mrg "") 305 1.10 mrg 306 1.10 mrg (define_expand "ftrunc<mode>2" 307 1.1 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 308 1.1 mrg (fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand")))] 309 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 310 1.1 mrg "") 311 1.10 mrg 312 1.10 mrg (define_expand "vector_ceil<mode>2" 313 1.1 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 314 1.1 mrg (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand")] 315 1.1 mrg UNSPEC_FRIP))] 316 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 317 1.1 mrg "") 318 1.10 mrg 319 1.10 mrg (define_expand "vector_floor<mode>2" 320 1.1 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 321 1.1 mrg (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand")] 322 1.1 mrg UNSPEC_FRIM))] 323 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 324 1.1 mrg "") 325 1.10 mrg 326 1.10 mrg (define_expand "vector_btrunc<mode>2" 327 1.1 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 328 1.1 mrg (fix:VEC_F (match_operand:VEC_F 1 "vfloat_operand")))] 329 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 330 1.1 mrg "") 331 1.10 mrg 332 1.10 mrg (define_expand "vector_copysign<mode>3" 333 1.10 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 334 1.1 mrg (unspec:VEC_F [(match_operand:VEC_F 1 "vfloat_operand") 335 1.1 mrg (match_operand:VEC_F 2 "vfloat_operand")] UNSPEC_COPYSIGN))] 336 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 337 1.1 mrg { 338 1.1 mrg if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) 339 1.1 mrg { 340 1.1 mrg emit_insn (gen_altivec_copysign_v4sf3 (operands[0], operands[1], 341 1.1 mrg operands[2])); 342 1.10 mrg DONE; 343 1.1 mrg } 344 1.1 mrg }) 345 1.1 mrg 346 1.3 mrg 348 1.1 mrg ;; Vector comparisons 349 1.1 mrg (define_expand "vcond<mode><mode>" 350 1.10 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 351 1.10 mrg (if_then_else:VEC_F 352 1.10 mrg (match_operator 3 "comparison_operator" 353 1.10 mrg [(match_operand:VEC_F 4 "vfloat_operand") 354 1.1 mrg (match_operand:VEC_F 5 "vfloat_operand")]) 355 1.1 mrg (match_operand:VEC_F 1 "vfloat_operand") 356 1.1 mrg (match_operand:VEC_F 2 "vfloat_operand")))] 357 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 358 1.1 mrg { 359 1.1 mrg if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], 360 1.14 mrg operands[3], operands[4], operands[5])) 361 1.10 mrg DONE; 362 1.1 mrg else 363 1.3 mrg gcc_unreachable (); 364 1.9 mrg }) 365 1.1 mrg 366 1.1 mrg (define_expand "vcond<mode><mode>" 367 1.9 mrg [(set (match_operand:VEC_I 0 "vint_operand") 368 1.9 mrg (if_then_else:VEC_I 369 1.9 mrg (match_operator 3 "comparison_operator" 370 1.9 mrg [(match_operand:VEC_I 4 "vint_operand") 371 1.3 mrg (match_operand:VEC_I 5 "vint_operand")]) 372 1.3 mrg (match_operand:VEC_I 1 "vector_int_reg_or_same_bit") 373 1.3 mrg (match_operand:VEC_I 2 "vector_int_reg_or_same_bit")))] 374 1.3 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 375 1.3 mrg { 376 1.3 mrg if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], 377 1.14 mrg operands[3], operands[4], operands[5])) 378 1.10 mrg DONE; 379 1.3 mrg else 380 1.3 mrg gcc_unreachable (); 381 1.10 mrg }) 382 1.3 mrg 383 1.3 mrg (define_expand "vcondv4sfv4si" 384 1.10 mrg [(set (match_operand:V4SF 0 "vfloat_operand") 385 1.10 mrg (if_then_else:V4SF 386 1.10 mrg (match_operator 3 "comparison_operator" 387 1.10 mrg [(match_operand:V4SI 4 "vint_operand") 388 1.3 mrg (match_operand:V4SI 5 "vint_operand")]) 389 1.3 mrg (match_operand:V4SF 1 "vfloat_operand") 390 1.3 mrg (match_operand:V4SF 2 "vfloat_operand")))] 391 1.3 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) 392 1.3 mrg && VECTOR_UNIT_ALTIVEC_P (V4SImode)" 393 1.3 mrg { 394 1.3 mrg if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], 395 1.14 mrg operands[3], operands[4], operands[5])) 396 1.10 mrg DONE; 397 1.3 mrg else 398 1.3 mrg gcc_unreachable (); 399 1.10 mrg }) 400 1.3 mrg 401 1.3 mrg (define_expand "vcondv4siv4sf" 402 1.10 mrg [(set (match_operand:V4SI 0 "vint_operand") 403 1.10 mrg (if_then_else:V4SI 404 1.10 mrg (match_operator 3 "comparison_operator" 405 1.10 mrg [(match_operand:V4SF 4 "vfloat_operand") 406 1.3 mrg (match_operand:V4SF 5 "vfloat_operand")]) 407 1.3 mrg (match_operand:V4SI 1 "vint_operand") 408 1.1 mrg (match_operand:V4SI 2 "vint_operand")))] 409 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) 410 1.1 mrg && VECTOR_UNIT_ALTIVEC_P (V4SImode)" 411 1.1 mrg { 412 1.1 mrg if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], 413 1.14 mrg operands[3], operands[4], operands[5])) 414 1.10 mrg DONE; 415 1.10 mrg else 416 1.10 mrg gcc_unreachable (); 417 1.10 mrg }) 418 1.10 mrg 419 1.10 mrg (define_expand "vcondv2dfv2di" 420 1.10 mrg [(set (match_operand:V2DF 0 "vfloat_operand") 421 1.10 mrg (if_then_else:V2DF 422 1.10 mrg (match_operator 3 "comparison_operator" 423 1.10 mrg [(match_operand:V2DI 4 "vint_operand") 424 1.10 mrg (match_operand:V2DI 5 "vint_operand")]) 425 1.10 mrg (match_operand:V2DF 1 "vfloat_operand") 426 1.10 mrg (match_operand:V2DF 2 "vfloat_operand")))] 427 1.10 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode) 428 1.10 mrg && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DImode)" 429 1.10 mrg { 430 1.10 mrg if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], 431 1.14 mrg operands[3], operands[4], operands[5])) 432 1.10 mrg DONE; 433 1.10 mrg else 434 1.10 mrg gcc_unreachable (); 435 1.10 mrg }) 436 1.10 mrg 437 1.10 mrg (define_expand "vcondv2div2df" 438 1.10 mrg [(set (match_operand:V2DI 0 "vint_operand") 439 1.10 mrg (if_then_else:V2DI 440 1.10 mrg (match_operator 3 "comparison_operator" 441 1.10 mrg [(match_operand:V2DF 4 "vfloat_operand") 442 1.10 mrg (match_operand:V2DF 5 "vfloat_operand")]) 443 1.10 mrg (match_operand:V2DI 1 "vint_operand") 444 1.10 mrg (match_operand:V2DI 2 "vint_operand")))] 445 1.10 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode) 446 1.10 mrg && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DImode)" 447 1.10 mrg { 448 1.10 mrg if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], 449 1.14 mrg operands[3], operands[4], operands[5])) 450 1.10 mrg DONE; 451 1.1 mrg else 452 1.3 mrg gcc_unreachable (); 453 1.9 mrg }) 454 1.1 mrg 455 1.1 mrg (define_expand "vcondu<mode><mode>" 456 1.9 mrg [(set (match_operand:VEC_I 0 "vint_operand") 457 1.9 mrg (if_then_else:VEC_I 458 1.9 mrg (match_operator 3 "comparison_operator" 459 1.9 mrg [(match_operand:VEC_I 4 "vint_operand") 460 1.3 mrg (match_operand:VEC_I 5 "vint_operand")]) 461 1.3 mrg (match_operand:VEC_I 1 "vector_int_reg_or_same_bit") 462 1.3 mrg (match_operand:VEC_I 2 "vector_int_reg_or_same_bit")))] 463 1.3 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 464 1.3 mrg { 465 1.3 mrg if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], 466 1.14 mrg operands[3], operands[4], operands[5])) 467 1.10 mrg DONE; 468 1.3 mrg else 469 1.3 mrg gcc_unreachable (); 470 1.10 mrg }) 471 1.3 mrg 472 1.3 mrg (define_expand "vconduv4sfv4si" 473 1.10 mrg [(set (match_operand:V4SF 0 "vfloat_operand") 474 1.10 mrg (if_then_else:V4SF 475 1.10 mrg (match_operator 3 "comparison_operator" 476 1.10 mrg [(match_operand:V4SI 4 "vint_operand") 477 1.3 mrg (match_operand:V4SI 5 "vint_operand")]) 478 1.3 mrg (match_operand:V4SF 1 "vfloat_operand") 479 1.1 mrg (match_operand:V4SF 2 "vfloat_operand")))] 480 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode) 481 1.1 mrg && VECTOR_UNIT_ALTIVEC_P (V4SImode)" 482 1.1 mrg { 483 1.1 mrg if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], 484 1.14 mrg operands[3], operands[4], operands[5])) 485 1.10 mrg DONE; 486 1.10 mrg else 487 1.10 mrg gcc_unreachable (); 488 1.10 mrg }) 489 1.10 mrg 490 1.10 mrg (define_expand "vconduv2dfv2di" 491 1.10 mrg [(set (match_operand:V2DF 0 "vfloat_operand") 492 1.10 mrg (if_then_else:V2DF 493 1.10 mrg (match_operator 3 "comparison_operator" 494 1.10 mrg [(match_operand:V2DI 4 "vint_operand") 495 1.10 mrg (match_operand:V2DI 5 "vint_operand")]) 496 1.10 mrg (match_operand:V2DF 1 "vfloat_operand") 497 1.10 mrg (match_operand:V2DF 2 "vfloat_operand")))] 498 1.10 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode) 499 1.10 mrg && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DImode)" 500 1.10 mrg { 501 1.10 mrg if (rs6000_emit_vector_cond_expr (operands[0], operands[1], operands[2], 502 1.14 mrg operands[3], operands[4], operands[5])) 503 1.10 mrg DONE; 504 1.1 mrg else 505 1.11 mrg gcc_unreachable (); 506 1.11 mrg }) 507 1.11 mrg 508 1.11 mrg ;; To support vector condition vectorization, define vcond_mask and vec_cmp. 509 1.11 mrg 510 1.11 mrg ;; Same mode for condition true/false values and predicate operand. 511 1.11 mrg (define_expand "vcond_mask_<mode><mode>" 512 1.11 mrg [(match_operand:VEC_I 0 "vint_operand") 513 1.11 mrg (match_operand:VEC_I 1 "vint_operand") 514 1.11 mrg (match_operand:VEC_I 2 "vint_operand") 515 1.11 mrg (match_operand:VEC_I 3 "vint_operand")] 516 1.12 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 517 1.12 mrg { 518 1.12 mrg emit_insn (gen_vector_select_<mode> (operands[0], operands[2], operands[1], 519 1.12 mrg operands[3])); 520 1.12 mrg DONE; 521 1.12 mrg }) 522 1.12 mrg 523 1.12 mrg ;; Condition true/false values are float but predicate operand is of 524 1.12 mrg ;; type integer vector with same element size. 525 1.12 mrg (define_expand "vcond_mask_<mode><VEC_int>" 526 1.12 mrg [(match_operand:VEC_F 0 "vfloat_operand") 527 1.12 mrg (match_operand:VEC_F 1 "vfloat_operand") 528 1.12 mrg (match_operand:VEC_F 2 "vfloat_operand") 529 1.12 mrg (match_operand:<VEC_INT> 3 "vint_operand")] 530 1.12 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 531 1.11 mrg { 532 1.11 mrg emit_insn (gen_vector_select_<mode> (operands[0], operands[2], operands[1], 533 1.11 mrg gen_lowpart (<MODE>mode, operands[3]))); 534 1.11 mrg DONE; 535 1.11 mrg }) 536 1.11 mrg 537 1.12 mrg ;; For signed integer vectors comparison. 538 1.12 mrg (define_expand "vec_cmp<mode><mode>" 539 1.12 mrg [(set (match_operand:VEC_I 0 "vint_operand") 540 1.11 mrg (match_operator 1 "signed_or_equality_comparison_operator" 541 1.11 mrg [(match_operand:VEC_I 2 "vint_operand") 542 1.11 mrg (match_operand:VEC_I 3 "vint_operand")]))] 543 1.11 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 544 1.11 mrg { 545 1.11 mrg enum rtx_code code = GET_CODE (operands[1]); 546 1.11 mrg rtx tmp = gen_reg_rtx (<MODE>mode); 547 1.11 mrg switch (code) 548 1.11 mrg { 549 1.11 mrg case NE: 550 1.11 mrg emit_insn (gen_vector_eq<mode> (operands[0], operands[2], operands[3])); 551 1.11 mrg emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[0])); 552 1.11 mrg break; 553 1.11 mrg case EQ: 554 1.11 mrg emit_insn (gen_vector_eq<mode> (operands[0], operands[2], operands[3])); 555 1.12 mrg break; 556 1.11 mrg case GE: 557 1.11 mrg emit_insn (gen_vector_nlt<mode> (operands[0],operands[2], operands[3], 558 1.11 mrg tmp)); 559 1.11 mrg break; 560 1.11 mrg case GT: 561 1.11 mrg emit_insn (gen_vector_gt<mode> (operands[0], operands[2], operands[3])); 562 1.12 mrg break; 563 1.11 mrg case LE: 564 1.11 mrg emit_insn (gen_vector_ngt<mode> (operands[0], operands[2], operands[3], 565 1.11 mrg tmp)); 566 1.11 mrg break; 567 1.11 mrg case LT: 568 1.11 mrg emit_insn (gen_vector_gt<mode> (operands[0], operands[3], operands[2])); 569 1.11 mrg break; 570 1.11 mrg default: 571 1.11 mrg gcc_unreachable (); 572 1.11 mrg break; 573 1.11 mrg } 574 1.11 mrg DONE; 575 1.11 mrg }) 576 1.11 mrg 577 1.12 mrg ;; For unsigned integer vectors comparison. 578 1.12 mrg (define_expand "vec_cmpu<mode><mode>" 579 1.12 mrg [(set (match_operand:VEC_I 0 "vint_operand") 580 1.11 mrg (match_operator 1 "unsigned_or_equality_comparison_operator" 581 1.11 mrg [(match_operand:VEC_I 2 "vint_operand") 582 1.11 mrg (match_operand:VEC_I 3 "vint_operand")]))] 583 1.11 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 584 1.11 mrg { 585 1.11 mrg enum rtx_code code = GET_CODE (operands[1]); 586 1.11 mrg rtx tmp = gen_reg_rtx (<MODE>mode); 587 1.11 mrg switch (code) 588 1.11 mrg { 589 1.11 mrg case NE: 590 1.11 mrg emit_insn (gen_vector_eq<mode> (operands[0], operands[2], operands[3])); 591 1.11 mrg emit_insn (gen_one_cmpl<mode>2 (operands[0], operands[0])); 592 1.11 mrg break; 593 1.11 mrg case EQ: 594 1.11 mrg emit_insn (gen_vector_eq<mode> (operands[0], operands[2], operands[3])); 595 1.12 mrg break; 596 1.11 mrg case GEU: 597 1.11 mrg emit_insn (gen_vector_nltu<mode> (operands[0], operands[2], operands[3], 598 1.11 mrg tmp)); 599 1.11 mrg break; 600 1.11 mrg case GTU: 601 1.11 mrg emit_insn (gen_vector_gtu<mode> (operands[0], operands[2], operands[3])); 602 1.12 mrg break; 603 1.11 mrg case LEU: 604 1.11 mrg emit_insn (gen_vector_ngtu<mode> (operands[0], operands[2], operands[3], 605 1.11 mrg tmp)); 606 1.11 mrg break; 607 1.11 mrg case LTU: 608 1.11 mrg emit_insn (gen_vector_gtu<mode> (operands[0], operands[3], operands[2])); 609 1.11 mrg break; 610 1.11 mrg default: 611 1.11 mrg gcc_unreachable (); 612 1.11 mrg break; 613 1.11 mrg } 614 1.12 mrg DONE; 615 1.12 mrg }) 616 1.12 mrg 617 1.12 mrg ;; For float point vectors comparison. 618 1.12 mrg (define_expand "vec_cmp<mode><VEC_int>" 619 1.12 mrg [(set (match_operand:<VEC_INT> 0 "vint_operand") 620 1.12 mrg (match_operator 1 "comparison_operator" 621 1.12 mrg [(match_operand:VEC_F 2 "vfloat_operand") 622 1.12 mrg (match_operand:VEC_F 3 "vfloat_operand")]))] 623 1.12 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 624 1.12 mrg { 625 1.12 mrg enum rtx_code code = GET_CODE (operands[1]); 626 1.12 mrg rtx res = gen_reg_rtx (<MODE>mode); 627 1.12 mrg switch (code) 628 1.12 mrg { 629 1.12 mrg case NE: 630 1.12 mrg emit_insn (gen_vector_ne<mode> (res, operands[2], operands[3])); 631 1.12 mrg break; 632 1.12 mrg case EQ: 633 1.12 mrg emit_insn (gen_vector_eq<mode> (res, operands[2], operands[3])); 634 1.12 mrg break; 635 1.12 mrg case GE: 636 1.12 mrg emit_insn (gen_vector_ge<mode> (res, operands[2], operands[3])); 637 1.12 mrg break; 638 1.12 mrg case GT: 639 1.12 mrg emit_insn (gen_vector_gt<mode> (res, operands[2], operands[3])); 640 1.12 mrg break; 641 1.12 mrg case LE: 642 1.12 mrg emit_insn (gen_vector_le<mode> (res, operands[2], operands[3])); 643 1.12 mrg break; 644 1.12 mrg case LT: 645 1.12 mrg emit_insn (gen_vector_lt<mode> (res, operands[2], operands[3])); 646 1.12 mrg break; 647 1.12 mrg case LTGT: 648 1.12 mrg emit_insn (gen_vector_ltgt<mode> (res, operands[2], operands[3])); 649 1.12 mrg break; 650 1.12 mrg case UNORDERED: 651 1.12 mrg emit_insn (gen_vector_unordered<mode> (res, operands[2], operands[3])); 652 1.12 mrg break; 653 1.12 mrg case ORDERED: 654 1.12 mrg emit_insn (gen_vector_ordered<mode> (res, operands[2], operands[3])); 655 1.12 mrg break; 656 1.12 mrg case UNEQ: 657 1.12 mrg emit_insn (gen_vector_uneq<mode> (res, operands[2], operands[3])); 658 1.12 mrg break; 659 1.12 mrg case UNGE: 660 1.12 mrg emit_insn (gen_vector_unge<mode> (res, operands[2], operands[3])); 661 1.12 mrg break; 662 1.12 mrg case UNGT: 663 1.12 mrg emit_insn (gen_vector_ungt<mode> (res, operands[2], operands[3])); 664 1.12 mrg break; 665 1.12 mrg case UNLE: 666 1.12 mrg emit_insn (gen_vector_unle<mode> (res, operands[2], operands[3])); 667 1.12 mrg break; 668 1.12 mrg case UNLT: 669 1.12 mrg emit_insn (gen_vector_unlt<mode> (res, operands[2], operands[3])); 670 1.12 mrg break; 671 1.12 mrg 672 1.12 mrg default: 673 1.12 mrg gcc_unreachable (); 674 1.12 mrg } 675 1.12 mrg 676 1.12 mrg emit_insn (gen_move_insn (operands[0], gen_lowpart (<VEC_INT>mode, res))); 677 1.1 mrg DONE; 678 1.10 mrg }) 679 1.10 mrg 680 1.10 mrg (define_expand "vector_eq<mode>" 681 1.1 mrg [(set (match_operand:VEC_C 0 "vlogical_operand") 682 1.1 mrg (eq:VEC_C (match_operand:VEC_C 1 "vlogical_operand") 683 1.1 mrg (match_operand:VEC_C 2 "vlogical_operand")))] 684 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 685 1.10 mrg "") 686 1.10 mrg 687 1.10 mrg (define_expand "vector_gt<mode>" 688 1.1 mrg [(set (match_operand:VEC_C 0 "vlogical_operand") 689 1.1 mrg (gt:VEC_C (match_operand:VEC_C 1 "vlogical_operand") 690 1.1 mrg (match_operand:VEC_C 2 "vlogical_operand")))] 691 1.7 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 692 1.7 mrg "") 693 1.10 mrg 694 1.10 mrg ; >= for integer vectors: swap operands and apply not-greater-than 695 1.10 mrg (define_expand "vector_nlt<mode>" 696 1.10 mrg [(set (match_operand:VEC_I 3 "vlogical_operand") 697 1.7 mrg (gt:VEC_I (match_operand:VEC_I 2 "vlogical_operand") 698 1.7 mrg (match_operand:VEC_I 1 "vlogical_operand"))) 699 1.7 mrg (set (match_operand:VEC_I 0 "vlogical_operand") 700 1.7 mrg (not:VEC_I (match_dup 3)))] 701 1.10 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 702 1.7 mrg { 703 1.14 mrg operands[3] = gen_reg_rtx_and_attrs (operands[0]); 704 1.14 mrg }) 705 1.14 mrg 706 1.14 mrg (define_expand "vector_nltv1ti" 707 1.14 mrg [(set (match_operand:V1TI 3 "vlogical_operand") 708 1.14 mrg (gt:V1TI (match_operand:V1TI 2 "vlogical_operand") 709 1.14 mrg (match_operand:V1TI 1 "vlogical_operand"))) 710 1.14 mrg (set (match_operand:V1TI 0 "vlogical_operand") 711 1.14 mrg (not:V1TI (match_dup 3)))] 712 1.14 mrg "TARGET_POWER10" 713 1.14 mrg { 714 1.1 mrg operands[3] = gen_reg_rtx_and_attrs (operands[0]); 715 1.10 mrg }) 716 1.10 mrg 717 1.10 mrg (define_expand "vector_gtu<mode>" 718 1.3 mrg [(set (match_operand:VEC_I 0 "vint_operand") 719 1.1 mrg (gtu:VEC_I (match_operand:VEC_I 1 "vint_operand") 720 1.1 mrg (match_operand:VEC_I 2 "vint_operand")))] 721 1.14 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 722 1.14 mrg "") 723 1.14 mrg 724 1.14 mrg (define_expand "vector_gtuv1ti" 725 1.14 mrg [(set (match_operand:V1TI 0 "altivec_register_operand") 726 1.14 mrg (gtu:V1TI (match_operand:V1TI 1 "altivec_register_operand") 727 1.14 mrg (match_operand:V1TI 2 "altivec_register_operand")))] 728 1.7 mrg "TARGET_POWER10" 729 1.7 mrg "") 730 1.10 mrg 731 1.10 mrg ; >= for integer vectors: swap operands and apply not-greater-than 732 1.10 mrg (define_expand "vector_nltu<mode>" 733 1.10 mrg [(set (match_operand:VEC_I 3 "vlogical_operand") 734 1.7 mrg (gtu:VEC_I (match_operand:VEC_I 2 "vlogical_operand") 735 1.7 mrg (match_operand:VEC_I 1 "vlogical_operand"))) 736 1.7 mrg (set (match_operand:VEC_I 0 "vlogical_operand") 737 1.7 mrg (not:VEC_I (match_dup 3)))] 738 1.10 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 739 1.7 mrg { 740 1.14 mrg operands[3] = gen_reg_rtx_and_attrs (operands[0]); 741 1.14 mrg }) 742 1.14 mrg 743 1.14 mrg (define_expand "vector_nltuv1ti" 744 1.14 mrg [(set (match_operand:V1TI 3 "vlogical_operand") 745 1.14 mrg (gtu:V1TI (match_operand:V1TI 2 "vlogical_operand") 746 1.14 mrg (match_operand:V1TI 1 "vlogical_operand"))) 747 1.14 mrg (set (match_operand:V1TI 0 "vlogical_operand") 748 1.14 mrg (not:V1TI (match_dup 3)))] 749 1.14 mrg "TARGET_POWER10" 750 1.14 mrg { 751 1.1 mrg operands[3] = gen_reg_rtx_and_attrs (operands[0]); 752 1.10 mrg }) 753 1.10 mrg 754 1.10 mrg (define_expand "vector_geu<mode>" 755 1.3 mrg [(set (match_operand:VEC_I 0 "vint_operand") 756 1.1 mrg (geu:VEC_I (match_operand:VEC_I 1 "vint_operand") 757 1.1 mrg (match_operand:VEC_I 2 "vint_operand")))] 758 1.7 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 759 1.7 mrg "") 760 1.10 mrg 761 1.10 mrg ; <= for integer vectors: apply not-greater-than 762 1.10 mrg (define_expand "vector_ngt<mode>" 763 1.10 mrg [(set (match_operand:VEC_I 3 "vlogical_operand") 764 1.7 mrg (gt:VEC_I (match_operand:VEC_I 1 "vlogical_operand") 765 1.7 mrg (match_operand:VEC_I 2 "vlogical_operand"))) 766 1.7 mrg (set (match_operand:VEC_I 0 "vlogical_operand") 767 1.7 mrg (not:VEC_I (match_dup 3)))] 768 1.10 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 769 1.7 mrg { 770 1.14 mrg operands[3] = gen_reg_rtx_and_attrs (operands[0]); 771 1.14 mrg }) 772 1.14 mrg 773 1.14 mrg (define_expand "vector_ngtv1ti" 774 1.14 mrg [(set (match_operand:V1TI 3 "vlogical_operand") 775 1.14 mrg (gt:V1TI (match_operand:V1TI 1 "vlogical_operand") 776 1.14 mrg (match_operand:V1TI 2 "vlogical_operand"))) 777 1.14 mrg (set (match_operand:V1TI 0 "vlogical_operand") 778 1.14 mrg (not:V1TI (match_dup 3)))] 779 1.14 mrg "TARGET_POWER10" 780 1.14 mrg { 781 1.7 mrg operands[3] = gen_reg_rtx_and_attrs (operands[0]); 782 1.10 mrg }) 783 1.10 mrg 784 1.10 mrg (define_expand "vector_ngtu<mode>" 785 1.10 mrg [(set (match_operand:VEC_I 3 "vlogical_operand") 786 1.7 mrg (gtu:VEC_I (match_operand:VEC_I 1 "vlogical_operand") 787 1.7 mrg (match_operand:VEC_I 2 "vlogical_operand"))) 788 1.7 mrg (set (match_operand:VEC_I 0 "vlogical_operand") 789 1.7 mrg (not:VEC_I (match_dup 3)))] 790 1.10 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 791 1.7 mrg { 792 1.14 mrg operands[3] = gen_reg_rtx_and_attrs (operands[0]); 793 1.14 mrg }) 794 1.14 mrg 795 1.14 mrg (define_expand "vector_ngtuv1ti" 796 1.14 mrg [(set (match_operand:V1TI 3 "vlogical_operand") 797 1.14 mrg (gtu:V1TI (match_operand:V1TI 1 "vlogical_operand") 798 1.14 mrg (match_operand:V1TI 2 "vlogical_operand"))) 799 1.14 mrg (set (match_operand:V1TI 0 "vlogical_operand") 800 1.14 mrg (not:V1TI (match_dup 3)))] 801 1.14 mrg "TARGET_POWER10" 802 1.14 mrg { 803 1.12 mrg operands[3] = gen_reg_rtx_and_attrs (operands[0]); 804 1.12 mrg }) 805 1.12 mrg 806 1.12 mrg ; There are 14 possible vector FP comparison operators, gt and eq of them have 807 1.12 mrg ; been expanded above, so just support 12 remaining operators here. 808 1.12 mrg 809 1.12 mrg ; For ge: 810 1.12 mrg (define_expand "vector_ge<mode>" 811 1.1 mrg [(set (match_operand:VEC_F 0 "vlogical_operand") 812 1.12 mrg (ge:VEC_F (match_operand:VEC_F 1 "vlogical_operand") 813 1.12 mrg (match_operand:VEC_F 2 "vlogical_operand")))] 814 1.12 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 815 1.12 mrg "") 816 1.12 mrg 817 1.12 mrg ; For lt/le/ne/ungt/unge/unlt/unle: 818 1.12 mrg ; lt(a,b) = gt(b,a) 819 1.12 mrg ; le(a,b) = ge(b,a) 820 1.12 mrg ; unge(a,b) = ~lt(a,b) 821 1.12 mrg ; unle(a,b) = ~gt(a,b) 822 1.12 mrg ; ne(a,b) = ~eq(a,b) 823 1.12 mrg ; ungt(a,b) = ~le(a,b) 824 1.12 mrg ; unlt(a,b) = ~ge(a,b) 825 1.12 mrg (define_insn_and_split "vector_<code><mode>" 826 1.12 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 827 1.12 mrg (vector_fp_comparison_simple:VEC_F 828 1.1 mrg (match_operand:VEC_F 1 "vfloat_operand") 829 1.12 mrg (match_operand:VEC_F 2 "vfloat_operand")))] 830 1.12 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && can_create_pseudo_p ()" 831 1.1 mrg "#" 832 1.12 mrg "&& can_create_pseudo_p ()" 833 1.12 mrg [(pc)] 834 1.12 mrg { 835 1.12 mrg enum rtx_code cond = <CODE>; 836 1.12 mrg bool need_invert = false; 837 1.12 mrg 838 1.12 mrg if (cond == UNLE || cond == UNLT || cond == NE || cond == UNGE 839 1.12 mrg || cond == UNGT) 840 1.12 mrg { 841 1.12 mrg cond = reverse_condition_maybe_unordered (cond); 842 1.12 mrg need_invert = true; 843 1.12 mrg } 844 1.12 mrg 845 1.12 mrg if (cond == LT || cond == LE) 846 1.12 mrg { 847 1.12 mrg cond = swap_condition (cond); 848 1.12 mrg std::swap (operands[1], operands[2]); 849 1.12 mrg } 850 1.12 mrg 851 1.12 mrg gcc_assert (cond == EQ || cond == GE || cond == GT); 852 1.12 mrg 853 1.12 mrg rtx comp = gen_rtx_fmt_ee (cond, <MODE>mode, operands[1], operands[2]); 854 1.12 mrg 855 1.12 mrg if (need_invert) 856 1.12 mrg { 857 1.12 mrg rtx res = gen_reg_rtx (<MODE>mode); 858 1.12 mrg emit_insn (gen_rtx_SET (res, comp)); 859 1.12 mrg emit_insn (gen_one_cmpl<mode>2 (operands[0], res)); 860 1.12 mrg } 861 1.12 mrg else 862 1.6 mrg emit_insn (gen_rtx_SET (operands[0], comp)); 863 1.1 mrg 864 1.12 mrg DONE; 865 1.12 mrg }) 866 1.12 mrg 867 1.12 mrg ; For ltgt/uneq/ordered/unordered: 868 1.12 mrg ; ltgt: gt(a,b) | gt(b,a) 869 1.12 mrg ; uneq: ~(gt(a,b) | gt(b,a)) 870 1.12 mrg ; ordered: ge(a,b) | ge(b,a) 871 1.12 mrg ; unordered: ~(ge(a,b) | ge(b,a)) 872 1.12 mrg (define_insn_and_split "vector_<code><mode>" 873 1.12 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 874 1.12 mrg (vector_fp_comparison_complex:VEC_F 875 1.1 mrg (match_operand:VEC_F 1 "vfloat_operand") 876 1.12 mrg (match_operand:VEC_F 2 "vfloat_operand")))] 877 1.12 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode) && can_create_pseudo_p ()" 878 1.1 mrg "#" 879 1.12 mrg "&& can_create_pseudo_p ()" 880 1.12 mrg [(pc)] 881 1.12 mrg { 882 1.12 mrg enum rtx_code cond = <CODE>; 883 1.12 mrg bool need_invert = false; 884 1.12 mrg 885 1.12 mrg if (cond == UNORDERED || cond == UNEQ) 886 1.12 mrg { 887 1.12 mrg cond = reverse_condition_maybe_unordered (cond); 888 1.12 mrg need_invert = true; 889 1.12 mrg } 890 1.12 mrg 891 1.12 mrg if (cond == LTGT) 892 1.12 mrg cond = GT; 893 1.12 mrg else if (cond == ORDERED) 894 1.12 mrg cond = GE; 895 1.12 mrg else 896 1.12 mrg gcc_unreachable (); 897 1.12 mrg 898 1.12 mrg rtx comp1 = gen_rtx_fmt_ee (cond, <MODE>mode, operands[1], operands[2]); 899 1.12 mrg rtx res1 = gen_reg_rtx (<MODE>mode); 900 1.12 mrg emit_insn (gen_rtx_SET (res1, comp1)); 901 1.1 mrg rtx comp2 = gen_rtx_fmt_ee (cond, <MODE>mode, operands[2], operands[1]); 902 1.12 mrg rtx res2 = gen_reg_rtx (<MODE>mode); 903 1.12 mrg emit_insn (gen_rtx_SET (res2, comp2)); 904 1.12 mrg 905 1.12 mrg if (need_invert) 906 1.12 mrg { 907 1.12 mrg rtx not1 = gen_rtx_fmt_e (NOT, <MODE>mode, res1); 908 1.12 mrg rtx not2 = gen_rtx_fmt_e (NOT, <MODE>mode, res2); 909 1.12 mrg rtx comp3 = gen_rtx_fmt_ee (AND, <MODE>mode, not1, not2); 910 1.12 mrg emit_insn (gen_rtx_SET (operands[0], comp3)); 911 1.1 mrg } 912 1.12 mrg else 913 1.10 mrg emit_insn (gen_ior<mode>3 (operands[0], res1, res2)); 914 1.1 mrg 915 1.1 mrg DONE; 916 1.1 mrg }) 917 1.1 mrg 918 1.10 mrg ;; Note the arguments for __builtin_altivec_vsel are op2, op1, mask 919 1.14 mrg ;; which is in the reverse order that we want 920 1.14 mrg (define_expand "vector_select_<mode>" 921 1.14 mrg [(set (match_operand:VEC_L 0 "vlogical_operand") 922 1.14 mrg (ior:VEC_L 923 1.14 mrg (and:VEC_L (not:VEC_L (match_operand:VEC_L 3 "vlogical_operand")) 924 1.14 mrg (match_operand:VEC_L 1 "vlogical_operand")) 925 1.1 mrg (and:VEC_L (match_dup 3) 926 1.1 mrg (match_operand:VEC_L 2 "vlogical_operand"))))] 927 1.10 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)") 928 1.14 mrg 929 1.14 mrg (define_expand "vector_select_<mode>_uns" 930 1.14 mrg [(set (match_operand:VEC_L 0 "vlogical_operand") 931 1.14 mrg (ior:VEC_L 932 1.14 mrg (and:VEC_L (not:VEC_L (match_operand:VEC_L 3 "vlogical_operand")) 933 1.14 mrg (match_operand:VEC_L 1 "vlogical_operand")) 934 1.1 mrg (and:VEC_L (match_dup 3) 935 1.1 mrg (match_operand:VEC_L 2 "vlogical_operand"))))] 936 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)") 937 1.1 mrg 938 1.1 mrg ;; Expansions that compare vectors producing a vector result and a predicate, 939 1.9 mrg ;; setting CR6 to indicate a combined status 940 1.10 mrg (define_expand "vector_eq_<mode>_p" 941 1.10 mrg [(parallel 942 1.1 mrg [(set (reg:CC CR6_REGNO) 943 1.10 mrg (unspec:CC [(eq:CC (match_operand:VEC_A 1 "vlogical_operand") 944 1.1 mrg (match_operand:VEC_A 2 "vlogical_operand"))] 945 1.1 mrg UNSPEC_PREDICATE)) 946 1.1 mrg (set (match_operand:VEC_A 0 "vlogical_operand") 947 1.1 mrg (eq:VEC_A (match_dup 1) 948 1.1 mrg (match_dup 2)))])] 949 1.14 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 950 1.14 mrg "") 951 1.14 mrg 952 1.14 mrg (define_expand "vector_eq_v1ti_p" 953 1.14 mrg [(parallel 954 1.14 mrg [(set (reg:CC CR6_REGNO) 955 1.14 mrg (unspec:CC [(eq:CC (match_operand:V1TI 1 "altivec_register_operand") 956 1.14 mrg (match_operand:V1TI 2 "altivec_register_operand"))] 957 1.14 mrg UNSPEC_PREDICATE)) 958 1.14 mrg (set (match_operand:V1TI 0 "vlogical_operand") 959 1.14 mrg (eq:V1TI (match_dup 1) 960 1.14 mrg (match_dup 2)))])] 961 1.9 mrg "TARGET_POWER10" 962 1.9 mrg "") 963 1.9 mrg 964 1.9 mrg ;; This expansion handles the V16QI, V8HI, and V4SI modes in the 965 1.9 mrg ;; implementation of the vec_all_ne built-in functions on Power9. 966 1.9 mrg (define_expand "vector_ne_<mode>_p" 967 1.9 mrg [(parallel 968 1.9 mrg [(set (reg:CC CR6_REGNO) 969 1.9 mrg (unspec:CC [(ne:CC (match_operand:VI 1 "vlogical_operand") 970 1.9 mrg (match_operand:VI 2 "vlogical_operand"))] 971 1.9 mrg UNSPEC_PREDICATE)) 972 1.9 mrg (set (match_dup 3) 973 1.9 mrg (ne:VI (match_dup 1) 974 1.9 mrg (match_dup 2)))]) 975 1.9 mrg (set (match_operand:SI 0 "register_operand" "=r") 976 1.9 mrg (lt:SI (reg:CC CR6_REGNO) 977 1.9 mrg (const_int 0)))] 978 1.9 mrg "TARGET_P9_VECTOR" 979 1.9 mrg { 980 1.9 mrg operands[3] = gen_reg_rtx (<MODE>mode); 981 1.9 mrg }) 982 1.9 mrg 983 1.9 mrg ;; This expansion handles the V16QI, V8HI, and V4SI modes in the 984 1.9 mrg ;; implementation of the vec_any_eq built-in functions on Power9. 985 1.9 mrg (define_expand "vector_ae_<mode>_p" 986 1.9 mrg [(parallel 987 1.9 mrg [(set (reg:CC CR6_REGNO) 988 1.9 mrg (unspec:CC [(ne:CC (match_operand:VI 1 "vlogical_operand") 989 1.9 mrg (match_operand:VI 2 "vlogical_operand"))] 990 1.9 mrg UNSPEC_PREDICATE)) 991 1.9 mrg (set (match_dup 3) 992 1.9 mrg (ne:VI (match_dup 1) 993 1.9 mrg (match_dup 2)))]) 994 1.9 mrg (set (match_operand:SI 0 "register_operand" "=r") 995 1.9 mrg (lt:SI (reg:CC CR6_REGNO) 996 1.9 mrg (const_int 0))) 997 1.9 mrg (set (match_dup 0) 998 1.9 mrg (xor:SI (match_dup 0) 999 1.9 mrg (const_int 1)))] 1000 1.9 mrg "TARGET_P9_VECTOR" 1001 1.9 mrg { 1002 1.9 mrg operands[3] = gen_reg_rtx (<MODE>mode); 1003 1.9 mrg }) 1004 1.9 mrg 1005 1.9 mrg ;; This expansion handles the V16QI, V8HI, and V4SI modes in the 1006 1.9 mrg ;; implementation of the vec_all_nez and vec_any_eqz built-in 1007 1.9 mrg ;; functions on Power9. 1008 1.9 mrg (define_expand "vector_nez_<mode>_p" 1009 1.9 mrg [(parallel 1010 1.9 mrg [(set (reg:CC CR6_REGNO) 1011 1.9 mrg (unspec:CC [(unspec:VI 1012 1.9 mrg [(match_operand:VI 1 "vlogical_operand") 1013 1.9 mrg (match_operand:VI 2 "vlogical_operand")] 1014 1.9 mrg UNSPEC_NEZ_P)] 1015 1.9 mrg UNSPEC_PREDICATE)) 1016 1.9 mrg (set (match_operand:VI 0 "vlogical_operand") 1017 1.9 mrg (unspec:VI [(match_dup 1) 1018 1.9 mrg (match_dup 2)] 1019 1.9 mrg UNSPEC_NEZ_P))])] 1020 1.9 mrg "TARGET_P9_VECTOR" 1021 1.9 mrg "") 1022 1.9 mrg 1023 1.9 mrg ;; This expansion handles the V2DI mode in the implementation of the 1024 1.9 mrg ;; vec_all_ne built-in function on Power9. 1025 1.9 mrg ;; 1026 1.9 mrg ;; Since the Power9 "xvcmpne<mode>." instruction does not support DImode, 1027 1.9 mrg ;; this expands into the same rtl that would be used for the Power8 1028 1.9 mrg ;; architecture. 1029 1.9 mrg (define_expand "vector_ne_v2di_p" 1030 1.9 mrg [(parallel 1031 1.9 mrg [(set (reg:CC CR6_REGNO) 1032 1.9 mrg (unspec:CC [(eq:CC (match_operand:V2DI 1 "vlogical_operand") 1033 1.9 mrg (match_operand:V2DI 2 "vlogical_operand"))] 1034 1.9 mrg UNSPEC_PREDICATE)) 1035 1.9 mrg (set (match_dup 3) 1036 1.9 mrg (eq:V2DI (match_dup 1) 1037 1.9 mrg (match_dup 2)))]) 1038 1.9 mrg (set (match_operand:SI 0 "register_operand" "=r") 1039 1.9 mrg (eq:SI (reg:CC CR6_REGNO) 1040 1.9 mrg (const_int 0)))] 1041 1.9 mrg "TARGET_P9_VECTOR" 1042 1.9 mrg { 1043 1.14 mrg operands[3] = gen_reg_rtx (V2DImode); 1044 1.14 mrg }) 1045 1.14 mrg 1046 1.14 mrg (define_expand "vector_ne_v1ti_p" 1047 1.14 mrg [(parallel 1048 1.14 mrg [(set (reg:CC CR6_REGNO) 1049 1.14 mrg (unspec:CC [(eq:CC (match_operand:V1TI 1 "altivec_register_operand") 1050 1.14 mrg (match_operand:V1TI 2 "altivec_register_operand"))] 1051 1.14 mrg UNSPEC_PREDICATE)) 1052 1.14 mrg (set (match_dup 3) 1053 1.14 mrg (eq:V1TI (match_dup 1) 1054 1.14 mrg (match_dup 2)))]) 1055 1.14 mrg (set (match_operand:SI 0 "register_operand" "=r") 1056 1.14 mrg (eq:SI (reg:CC CR6_REGNO) 1057 1.14 mrg (const_int 0)))] 1058 1.14 mrg "TARGET_POWER10" 1059 1.14 mrg { 1060 1.9 mrg operands[3] = gen_reg_rtx (V1TImode); 1061 1.9 mrg }) 1062 1.9 mrg 1063 1.9 mrg ;; This expansion handles the V2DI mode in the implementation of the 1064 1.9 mrg ;; vec_any_eq built-in function on Power9. 1065 1.9 mrg ;; 1066 1.9 mrg ;; Since the Power9 "xvcmpne<mode>." instruction does not support DImode, 1067 1.9 mrg ;; this expands into the same rtl that would be used for the Power8 1068 1.9 mrg ;; architecture. 1069 1.9 mrg (define_expand "vector_ae_v2di_p" 1070 1.9 mrg [(parallel 1071 1.9 mrg [(set (reg:CC CR6_REGNO) 1072 1.9 mrg (unspec:CC [(eq:CC (match_operand:V2DI 1 "vlogical_operand") 1073 1.9 mrg (match_operand:V2DI 2 "vlogical_operand"))] 1074 1.9 mrg UNSPEC_PREDICATE)) 1075 1.9 mrg (set (match_dup 3) 1076 1.9 mrg (eq:V2DI (match_dup 1) 1077 1.9 mrg (match_dup 2)))]) 1078 1.9 mrg (set (match_operand:SI 0 "register_operand" "=r") 1079 1.9 mrg (eq:SI (reg:CC CR6_REGNO) 1080 1.9 mrg (const_int 0))) 1081 1.9 mrg (set (match_dup 0) 1082 1.9 mrg (xor:SI (match_dup 0) 1083 1.9 mrg (const_int 1)))] 1084 1.9 mrg "TARGET_P9_VECTOR" 1085 1.9 mrg { 1086 1.14 mrg operands[3] = gen_reg_rtx (V2DImode); 1087 1.14 mrg }) 1088 1.14 mrg 1089 1.14 mrg (define_expand "vector_ae_v1ti_p" 1090 1.14 mrg [(parallel 1091 1.14 mrg [(set (reg:CC CR6_REGNO) 1092 1.14 mrg (unspec:CC [(eq:CC (match_operand:V1TI 1 "altivec_register_operand") 1093 1.14 mrg (match_operand:V1TI 2 "altivec_register_operand"))] 1094 1.14 mrg UNSPEC_PREDICATE)) 1095 1.14 mrg (set (match_dup 3) 1096 1.14 mrg (eq:V1TI (match_dup 1) 1097 1.14 mrg (match_dup 2)))]) 1098 1.14 mrg (set (match_operand:SI 0 "register_operand" "=r") 1099 1.14 mrg (eq:SI (reg:CC CR6_REGNO) 1100 1.14 mrg (const_int 0))) 1101 1.14 mrg (set (match_dup 0) 1102 1.14 mrg (xor:SI (match_dup 0) 1103 1.14 mrg (const_int 1)))] 1104 1.14 mrg "TARGET_POWER10" 1105 1.14 mrg { 1106 1.9 mrg operands[3] = gen_reg_rtx (V1TImode); 1107 1.9 mrg }) 1108 1.9 mrg 1109 1.9 mrg ;; This expansion handles the V4SF and V2DF modes in the Power9 1110 1.9 mrg ;; implementation of the vec_all_ne built-in functions. Note that the 1111 1.9 mrg ;; expansions for this pattern with these modes makes no use of power9- 1112 1.9 mrg ;; specific instructions since there are no new power9 instructions 1113 1.9 mrg ;; for vector compare not equal with floating point arguments. 1114 1.9 mrg (define_expand "vector_ne_<mode>_p" 1115 1.9 mrg [(parallel 1116 1.9 mrg [(set (reg:CC CR6_REGNO) 1117 1.9 mrg (unspec:CC [(eq:CC (match_operand:VEC_F 1 "vlogical_operand") 1118 1.9 mrg (match_operand:VEC_F 2 "vlogical_operand"))] 1119 1.9 mrg UNSPEC_PREDICATE)) 1120 1.9 mrg (set (match_dup 3) 1121 1.9 mrg (eq:VEC_F (match_dup 1) 1122 1.9 mrg (match_dup 2)))]) 1123 1.9 mrg (set (match_operand:SI 0 "register_operand" "=r") 1124 1.9 mrg (eq:SI (reg:CC CR6_REGNO) 1125 1.9 mrg (const_int 0)))] 1126 1.9 mrg "TARGET_P9_VECTOR" 1127 1.9 mrg { 1128 1.9 mrg operands[3] = gen_reg_rtx (<MODE>mode); 1129 1.9 mrg }) 1130 1.9 mrg 1131 1.9 mrg ;; This expansion handles the V4SF and V2DF modes in the Power9 1132 1.9 mrg ;; implementation of the vec_any_eq built-in functions. Note that the 1133 1.9 mrg ;; expansions for this pattern with these modes makes no use of power9- 1134 1.9 mrg ;; specific instructions since there are no new power9 instructions 1135 1.9 mrg ;; for vector compare not equal with floating point arguments. 1136 1.9 mrg (define_expand "vector_ae_<mode>_p" 1137 1.9 mrg [(parallel 1138 1.9 mrg [(set (reg:CC CR6_REGNO) 1139 1.9 mrg (unspec:CC [(eq:CC (match_operand:VEC_F 1 "vlogical_operand") 1140 1.9 mrg (match_operand:VEC_F 2 "vlogical_operand"))] 1141 1.9 mrg UNSPEC_PREDICATE)) 1142 1.9 mrg (set (match_dup 3) 1143 1.9 mrg (eq:VEC_F (match_dup 1) 1144 1.9 mrg (match_dup 2)))]) 1145 1.9 mrg (set (match_operand:SI 0 "register_operand" "=r") 1146 1.9 mrg (eq:SI (reg:CC CR6_REGNO) 1147 1.9 mrg (const_int 0))) 1148 1.9 mrg (set (match_dup 0) 1149 1.9 mrg (xor:SI (match_dup 0) 1150 1.9 mrg (const_int 1)))] 1151 1.9 mrg "TARGET_P9_VECTOR" 1152 1.9 mrg { 1153 1.1 mrg operands[3] = gen_reg_rtx (<MODE>mode); 1154 1.1 mrg }) 1155 1.9 mrg 1156 1.10 mrg (define_expand "vector_gt_<mode>_p" 1157 1.10 mrg [(parallel 1158 1.1 mrg [(set (reg:CC CR6_REGNO) 1159 1.10 mrg (unspec:CC [(gt:CC (match_operand:VEC_A 1 "vlogical_operand") 1160 1.1 mrg (match_operand:VEC_A 2 "vlogical_operand"))] 1161 1.1 mrg UNSPEC_PREDICATE)) 1162 1.1 mrg (set (match_operand:VEC_A 0 "vlogical_operand") 1163 1.1 mrg (gt:VEC_A (match_dup 1) 1164 1.1 mrg (match_dup 2)))])] 1165 1.14 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 1166 1.14 mrg "") 1167 1.14 mrg 1168 1.14 mrg (define_expand "vector_gt_v1ti_p" 1169 1.14 mrg [(parallel 1170 1.14 mrg [(set (reg:CC CR6_REGNO) 1171 1.14 mrg (unspec:CC [(gt:CC (match_operand:V1TI 1 "vlogical_operand") 1172 1.14 mrg (match_operand:V1TI 2 "vlogical_operand"))] 1173 1.14 mrg UNSPEC_PREDICATE)) 1174 1.14 mrg (set (match_operand:V1TI 0 "vlogical_operand") 1175 1.14 mrg (gt:V1TI (match_dup 1) 1176 1.14 mrg (match_dup 2)))])] 1177 1.1 mrg "TARGET_POWER10" 1178 1.1 mrg "") 1179 1.9 mrg 1180 1.10 mrg (define_expand "vector_ge_<mode>_p" 1181 1.10 mrg [(parallel 1182 1.1 mrg [(set (reg:CC CR6_REGNO) 1183 1.10 mrg (unspec:CC [(ge:CC (match_operand:VEC_F 1 "vfloat_operand") 1184 1.1 mrg (match_operand:VEC_F 2 "vfloat_operand"))] 1185 1.1 mrg UNSPEC_PREDICATE)) 1186 1.1 mrg (set (match_operand:VEC_F 0 "vfloat_operand") 1187 1.1 mrg (ge:VEC_F (match_dup 1) 1188 1.1 mrg (match_dup 2)))])] 1189 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 1190 1.1 mrg "") 1191 1.9 mrg 1192 1.10 mrg (define_expand "vector_gtu_<mode>_p" 1193 1.10 mrg [(parallel 1194 1.1 mrg [(set (reg:CC CR6_REGNO) 1195 1.10 mrg (unspec:CC [(gtu:CC (match_operand:VEC_I 1 "vint_operand") 1196 1.1 mrg (match_operand:VEC_I 2 "vint_operand"))] 1197 1.1 mrg UNSPEC_PREDICATE)) 1198 1.1 mrg (set (match_operand:VEC_I 0 "vlogical_operand") 1199 1.1 mrg (gtu:VEC_I (match_dup 1) 1200 1.1 mrg (match_dup 2)))])] 1201 1.14 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 1202 1.14 mrg "") 1203 1.14 mrg 1204 1.14 mrg (define_expand "vector_gtu_v1ti_p" 1205 1.14 mrg [(parallel 1206 1.14 mrg [(set (reg:CC CR6_REGNO) 1207 1.14 mrg (unspec:CC [(gtu:CC (match_operand:V1TI 1 "altivec_register_operand") 1208 1.14 mrg (match_operand:V1TI 2 "altivec_register_operand"))] 1209 1.14 mrg UNSPEC_PREDICATE)) 1210 1.14 mrg (set (match_operand:V1TI 0 "altivec_register_operand") 1211 1.14 mrg (gtu:V1TI (match_dup 1) 1212 1.14 mrg (match_dup 2)))])] 1213 1.1 mrg "TARGET_POWER10" 1214 1.1 mrg "") 1215 1.9 mrg 1216 1.9 mrg ;; AltiVec/VSX predicates. 1217 1.9 mrg 1218 1.9 mrg ;; This expansion is triggered during expansion of predicate built-in 1219 1.1 mrg ;; functions (built-ins defined with the RS6000_BUILTIN_P macro) by the 1220 1.1 mrg ;; altivec_expand_predicate_builtin() function when the value of the 1221 1.9 mrg ;; integer constant first argument equals zero (aka __CR6_EQ in altivec.h). 1222 1.1 mrg (define_expand "cr6_test_for_zero" 1223 1.1 mrg [(set (match_operand:SI 0 "register_operand" "=r") 1224 1.1 mrg (eq:SI (reg:CC CR6_REGNO) 1225 1.1 mrg (const_int 0)))] 1226 1.9 mrg "TARGET_ALTIVEC || TARGET_VSX" 1227 1.9 mrg "") 1228 1.9 mrg 1229 1.9 mrg ;; This expansion is triggered during expansion of predicate built-in 1230 1.1 mrg ;; functions (built-ins defined with the RS6000_BUILTIN_P macro) by the 1231 1.1 mrg ;; altivec_expand_predicate_builtin() function when the value of the 1232 1.9 mrg ;; integer constant first argument equals one (aka __CR6_EQ_REV in altivec.h). 1233 1.1 mrg (define_expand "cr6_test_for_zero_reverse" 1234 1.5 mrg [(set (match_operand:SI 0 "register_operand" "=r") 1235 1.5 mrg (eq:SI (reg:CC CR6_REGNO) 1236 1.5 mrg (const_int 0))) 1237 1.1 mrg (set (match_dup 0) 1238 1.1 mrg (xor:SI (match_dup 0) 1239 1.1 mrg (const_int 1)))] 1240 1.9 mrg "TARGET_ALTIVEC || TARGET_VSX" 1241 1.9 mrg "") 1242 1.9 mrg 1243 1.9 mrg ;; This expansion is triggered during expansion of predicate built-in 1244 1.1 mrg ;; functions (built-ins defined with the RS6000_BUILTIN_P macro) by the 1245 1.1 mrg ;; altivec_expand_predicate_builtin() function when the value of the 1246 1.9 mrg ;; integer constant first argument equals two (aka __CR6_LT in altivec.h). 1247 1.1 mrg (define_expand "cr6_test_for_lt" 1248 1.1 mrg [(set (match_operand:SI 0 "register_operand" "=r") 1249 1.1 mrg (lt:SI (reg:CC CR6_REGNO) 1250 1.1 mrg (const_int 0)))] 1251 1.9 mrg "TARGET_ALTIVEC || TARGET_VSX" 1252 1.9 mrg "") 1253 1.9 mrg 1254 1.9 mrg ;; This expansion is triggered during expansion of predicate built-in 1255 1.9 mrg ;; functions (built-ins defined with the RS6000_BUILTIN_P macro) by the 1256 1.1 mrg ;; altivec_expand_predicate_builtin() function when the value of the 1257 1.1 mrg ;; integer constant first argument equals three 1258 1.9 mrg ;; (aka __CR6_LT_REV in altivec.h). 1259 1.1 mrg (define_expand "cr6_test_for_lt_reverse" 1260 1.5 mrg [(set (match_operand:SI 0 "register_operand" "=r") 1261 1.5 mrg (lt:SI (reg:CC CR6_REGNO) 1262 1.5 mrg (const_int 0))) 1263 1.1 mrg (set (match_dup 0) 1264 1.1 mrg (xor:SI (match_dup 0) 1265 1.1 mrg (const_int 1)))] 1266 1.1 mrg "TARGET_ALTIVEC || TARGET_VSX" 1267 1.3 mrg "") 1268 1.3 mrg 1269 1.10 mrg 1271 1.3 mrg ;; Vector count leading zeros 1272 1.3 mrg (define_expand "clz<mode>2" 1273 1.7 mrg [(set (match_operand:VEC_I 0 "register_operand") 1274 1.7 mrg (clz:VEC_I (match_operand:VEC_I 1 "register_operand")))] 1275 1.10 mrg "TARGET_P8_VECTOR") 1276 1.10 mrg 1277 1.7 mrg ;; Vector count trailing zeros 1278 1.7 mrg (define_expand "ctz<mode>2" 1279 1.3 mrg [(set (match_operand:VEC_I 0 "register_operand") 1280 1.3 mrg (ctz:VEC_I (match_operand:VEC_I 1 "register_operand")))] 1281 1.10 mrg "TARGET_P9_VECTOR") 1282 1.10 mrg 1283 1.3 mrg ;; Vector population count 1284 1.1 mrg (define_expand "popcount<mode>2" 1285 1.7 mrg [(set (match_operand:VEC_I 0 "register_operand") 1286 1.7 mrg (popcount:VEC_I (match_operand:VEC_I 1 "register_operand")))] 1287 1.10 mrg "TARGET_P8_VECTOR") 1288 1.10 mrg 1289 1.13 mrg ;; Vector parity 1290 1.13 mrg (define_expand "parity<mode>2" 1291 1.13 mrg [(set (match_operand:VEC_IP 0 "register_operand") 1292 1.13 mrg (parity:VEC_IP (match_operand:VEC_IP 1 "register_operand")))] 1293 1.13 mrg "TARGET_P9_VECTOR" 1294 1.13 mrg { 1295 1.13 mrg rtx op1 = gen_lowpart (V16QImode, operands[1]); 1296 1.13 mrg rtx res = gen_reg_rtx (V16QImode); 1297 1.13 mrg emit_insn (gen_popcountv16qi2 (res, op1)); 1298 1.13 mrg emit_insn (gen_rs6000_vprtyb<mode>2 (operands[0], 1299 1.7 mrg gen_lowpart (<MODE>mode, res))); 1300 1.3 mrg 1301 1.1 mrg DONE; 1302 1.1 mrg }) 1303 1.10 mrg 1304 1.10 mrg 1306 1.1 mrg ;; Same size conversions 1307 1.1 mrg (define_expand "float<VEC_int><mode>2" 1308 1.1 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 1309 1.1 mrg (float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand")))] 1310 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 1311 1.1 mrg { 1312 1.10 mrg if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) 1313 1.1 mrg { 1314 1.3 mrg emit_insn (gen_altivec_vcfsx (operands[0], operands[1], const0_rtx)); 1315 1.10 mrg DONE; 1316 1.10 mrg } 1317 1.1 mrg }) 1318 1.1 mrg 1319 1.1 mrg (define_expand "floatuns<VEC_int><mode>2" 1320 1.1 mrg [(set (match_operand:VEC_F 0 "vfloat_operand") 1321 1.1 mrg (unsigned_float:VEC_F (match_operand:<VEC_INT> 1 "vint_operand")))] 1322 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 1323 1.1 mrg { 1324 1.10 mrg if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) 1325 1.1 mrg { 1326 1.1 mrg emit_insn (gen_altivec_vcfux (operands[0], operands[1], const0_rtx)); 1327 1.10 mrg DONE; 1328 1.10 mrg } 1329 1.1 mrg }) 1330 1.1 mrg 1331 1.1 mrg (define_expand "fix_trunc<mode><VEC_int>2" 1332 1.1 mrg [(set (match_operand:<VEC_INT> 0 "vint_operand") 1333 1.1 mrg (fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand")))] 1334 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 1335 1.1 mrg { 1336 1.10 mrg if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) 1337 1.1 mrg { 1338 1.1 mrg emit_insn (gen_altivec_vctsxs (operands[0], operands[1], const0_rtx)); 1339 1.10 mrg DONE; 1340 1.10 mrg } 1341 1.1 mrg }) 1342 1.1 mrg 1343 1.1 mrg (define_expand "fixuns_trunc<mode><VEC_int>2" 1344 1.1 mrg [(set (match_operand:<VEC_INT> 0 "vint_operand") 1345 1.1 mrg (unsigned_fix:<VEC_INT> (match_operand:VEC_F 1 "vfloat_operand")))] 1346 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 1347 1.1 mrg { 1348 1.10 mrg if (<MODE>mode == V4SFmode && VECTOR_UNIT_ALTIVEC_P (<MODE>mode)) 1349 1.1 mrg { 1350 1.1 mrg emit_insn (gen_altivec_vctuxs (operands[0], operands[1], const0_rtx)); 1351 1.1 mrg DONE; 1352 1.10 mrg } 1353 1.10 mrg }) 1354 1.10 mrg 1355 1.1 mrg 1357 1.1 mrg ;; Vector initialization, set, extract 1358 1.1 mrg (define_expand "vec_init<mode><VEC_base_l>" 1359 1.1 mrg [(match_operand:VEC_E 0 "vlogical_operand") 1360 1.1 mrg (match_operand:VEC_E 1 "")] 1361 1.1 mrg "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" 1362 1.10 mrg { 1363 1.10 mrg rs6000_expand_vector_init (operands[0], operands[1]); 1364 1.14 mrg DONE; 1365 1.1 mrg }) 1366 1.1 mrg 1367 1.14 mrg (define_expand "vec_set<mode>" 1368 1.1 mrg [(match_operand:VEC_E 0 "vlogical_operand") 1369 1.1 mrg (match_operand:<VEC_base> 1 "register_operand") 1370 1.1 mrg (match_operand 2 "vec_set_index_operand")] 1371 1.10 mrg "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" 1372 1.10 mrg { 1373 1.10 mrg rs6000_expand_vector_set (operands[0], operands[1], operands[2]); 1374 1.10 mrg DONE; 1375 1.1 mrg }) 1376 1.1 mrg 1377 1.9 mrg (define_expand "vec_extract<mode><VEC_base_l>" 1378 1.1 mrg [(match_operand:<VEC_base> 0 "register_operand") 1379 1.1 mrg (match_operand:VEC_E 1 "vlogical_operand") 1380 1.1 mrg (match_operand 2 "const_int_operand")] 1381 1.1 mrg "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" 1382 1.1 mrg { 1383 1.10 mrg rs6000_expand_vector_extract (operands[0], operands[1], operands[2]); 1384 1.10 mrg DONE; 1385 1.10 mrg }) 1386 1.1 mrg 1388 1.1 mrg ;; Convert double word types to single word types 1389 1.1 mrg (define_expand "vec_pack_trunc_v2df" 1390 1.1 mrg [(match_operand:V4SF 0 "vfloat_operand") 1391 1.1 mrg (match_operand:V2DF 1 "vfloat_operand") 1392 1.1 mrg (match_operand:V2DF 2 "vfloat_operand")] 1393 1.3 mrg "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" 1394 1.1 mrg { 1395 1.1 mrg rtx r1 = gen_reg_rtx (V4SFmode); 1396 1.1 mrg rtx r2 = gen_reg_rtx (V4SFmode); 1397 1.1 mrg 1398 1.10 mrg emit_insn (gen_vsx_xvcvdpsp (r1, operands[1])); 1399 1.10 mrg emit_insn (gen_vsx_xvcvdpsp (r2, operands[2])); 1400 1.10 mrg rs6000_expand_extract_even (operands[0], r1, r2); 1401 1.1 mrg DONE; 1402 1.1 mrg }) 1403 1.1 mrg 1404 1.1 mrg (define_expand "vec_pack_sfix_trunc_v2df" 1405 1.1 mrg [(match_operand:V4SI 0 "vint_operand") 1406 1.1 mrg (match_operand:V2DF 1 "vfloat_operand") 1407 1.1 mrg (match_operand:V2DF 2 "vfloat_operand")] 1408 1.3 mrg "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" 1409 1.1 mrg { 1410 1.1 mrg rtx r1 = gen_reg_rtx (V4SImode); 1411 1.1 mrg rtx r2 = gen_reg_rtx (V4SImode); 1412 1.1 mrg 1413 1.10 mrg emit_insn (gen_vsx_xvcvdpsxws (r1, operands[1])); 1414 1.10 mrg emit_insn (gen_vsx_xvcvdpsxws (r2, operands[2])); 1415 1.10 mrg rs6000_expand_extract_even (operands[0], r1, r2); 1416 1.1 mrg DONE; 1417 1.1 mrg }) 1418 1.1 mrg 1419 1.1 mrg (define_expand "vec_pack_ufix_trunc_v2df" 1420 1.1 mrg [(match_operand:V4SI 0 "vint_operand") 1421 1.1 mrg (match_operand:V2DF 1 "vfloat_operand") 1422 1.1 mrg (match_operand:V2DF 2 "vfloat_operand")] 1423 1.3 mrg "VECTOR_UNIT_VSX_P (V2DFmode) && TARGET_ALTIVEC" 1424 1.1 mrg { 1425 1.1 mrg rtx r1 = gen_reg_rtx (V4SImode); 1426 1.1 mrg rtx r2 = gen_reg_rtx (V4SImode); 1427 1.1 mrg 1428 1.1 mrg emit_insn (gen_vsx_xvcvdpuxws (r1, operands[1])); 1429 1.10 mrg emit_insn (gen_vsx_xvcvdpuxws (r2, operands[2])); 1430 1.10 mrg rs6000_expand_extract_even (operands[0], r1, r2); 1431 1.1 mrg DONE; 1432 1.1 mrg }) 1433 1.1 mrg 1434 1.1 mrg ;; Convert single word types to double word 1435 1.3 mrg (define_expand "vec_unpacks_hi_v4sf" 1436 1.1 mrg [(match_operand:V2DF 0 "vfloat_operand") 1437 1.1 mrg (match_operand:V4SF 1 "vfloat_operand")] 1438 1.1 mrg "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" 1439 1.1 mrg { 1440 1.1 mrg rtx reg = gen_reg_rtx (V4SFmode); 1441 1.10 mrg 1442 1.10 mrg rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN); 1443 1.1 mrg emit_insn (gen_vsx_xvcvspdp (operands[0], reg)); 1444 1.1 mrg DONE; 1445 1.1 mrg }) 1446 1.1 mrg 1447 1.3 mrg (define_expand "vec_unpacks_lo_v4sf" 1448 1.1 mrg [(match_operand:V2DF 0 "vfloat_operand") 1449 1.1 mrg (match_operand:V4SF 1 "vfloat_operand")] 1450 1.1 mrg "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)" 1451 1.1 mrg { 1452 1.1 mrg rtx reg = gen_reg_rtx (V4SFmode); 1453 1.10 mrg 1454 1.10 mrg rs6000_expand_interleave (reg, operands[1], operands[1], !BYTES_BIG_ENDIAN); 1455 1.1 mrg emit_insn (gen_vsx_xvcvspdp (operands[0], reg)); 1456 1.1 mrg DONE; 1457 1.1 mrg }) 1458 1.1 mrg 1459 1.3 mrg (define_expand "vec_unpacks_float_hi_v4si" 1460 1.1 mrg [(match_operand:V2DF 0 "vfloat_operand") 1461 1.1 mrg (match_operand:V4SI 1 "vint_operand")] 1462 1.1 mrg "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" 1463 1.1 mrg { 1464 1.1 mrg rtx reg = gen_reg_rtx (V4SImode); 1465 1.10 mrg 1466 1.10 mrg rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN); 1467 1.1 mrg emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg)); 1468 1.1 mrg DONE; 1469 1.1 mrg }) 1470 1.1 mrg 1471 1.3 mrg (define_expand "vec_unpacks_float_lo_v4si" 1472 1.1 mrg [(match_operand:V2DF 0 "vfloat_operand") 1473 1.1 mrg (match_operand:V4SI 1 "vint_operand")] 1474 1.1 mrg "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" 1475 1.1 mrg { 1476 1.1 mrg rtx reg = gen_reg_rtx (V4SImode); 1477 1.10 mrg 1478 1.10 mrg rs6000_expand_interleave (reg, operands[1], operands[1], !BYTES_BIG_ENDIAN); 1479 1.1 mrg emit_insn (gen_vsx_xvcvsxwdp (operands[0], reg)); 1480 1.1 mrg DONE; 1481 1.1 mrg }) 1482 1.1 mrg 1483 1.3 mrg (define_expand "vec_unpacku_float_hi_v4si" 1484 1.1 mrg [(match_operand:V2DF 0 "vfloat_operand") 1485 1.1 mrg (match_operand:V4SI 1 "vint_operand")] 1486 1.1 mrg "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" 1487 1.1 mrg { 1488 1.1 mrg rtx reg = gen_reg_rtx (V4SImode); 1489 1.10 mrg 1490 1.10 mrg rs6000_expand_interleave (reg, operands[1], operands[1], BYTES_BIG_ENDIAN); 1491 1.1 mrg emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg)); 1492 1.1 mrg DONE; 1493 1.1 mrg }) 1494 1.1 mrg 1495 1.3 mrg (define_expand "vec_unpacku_float_lo_v4si" 1496 1.1 mrg [(match_operand:V2DF 0 "vfloat_operand") 1497 1.1 mrg (match_operand:V4SI 1 "vint_operand")] 1498 1.1 mrg "VECTOR_UNIT_VSX_P (V2DFmode) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SImode)" 1499 1.1 mrg { 1500 1.1 mrg rtx reg = gen_reg_rtx (V4SImode); 1501 1.1 mrg 1502 1.1 mrg rs6000_expand_interleave (reg, operands[1], operands[1], !BYTES_BIG_ENDIAN); 1503 1.10 mrg emit_insn (gen_vsx_xvcvuxwdp (operands[0], reg)); 1504 1.10 mrg DONE; 1505 1.10 mrg }) 1506 1.10 mrg 1507 1.1 mrg 1509 1.3 mrg ;; Align vector loads with a permute. 1510 1.3 mrg (define_expand "vec_realign_load_<mode>" 1511 1.3 mrg [(match_operand:VEC_K 0 "vlogical_operand") 1512 1.3 mrg (match_operand:VEC_K 1 "vlogical_operand") 1513 1.3 mrg (match_operand:VEC_K 2 "vlogical_operand") 1514 1.3 mrg (match_operand:V16QI 3 "vlogical_operand")] 1515 1.3 mrg "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" 1516 1.3 mrg { 1517 1.3 mrg if (BYTES_BIG_ENDIAN) 1518 1.3 mrg emit_insn (gen_altivec_vperm_<mode> (operands[0], operands[1], 1519 1.3 mrg operands[2], operands[3])); 1520 1.3 mrg else 1521 1.3 mrg { 1522 1.1 mrg /* We have changed lvsr to lvsl, so to complete the transformation 1523 1.1 mrg of vperm for LE, we must swap the inputs. */ 1524 1.1 mrg rtx unspec = gen_rtx_UNSPEC (<MODE>mode, 1525 1.1 mrg gen_rtvec (3, operands[2], 1526 1.1 mrg operands[1], operands[3]), 1527 1.1 mrg UNSPEC_VPERM); 1528 1.10 mrg emit_move_insn (operands[0], unspec); 1529 1.10 mrg } 1530 1.1 mrg DONE; 1531 1.12 mrg }) 1532 1.12 mrg 1533 1.12 mrg ;; Under VSX, vectors of 4/8 byte alignments do not need to be aligned 1534 1.12 mrg ;; since the load already handles it. 1535 1.1 mrg (define_expand "movmisalign<mode>" 1536 1.5 mrg [(set (match_operand:VEC_N 0 "nonimmediate_operand") 1537 1.1 mrg (match_operand:VEC_N 1 "any_operand"))] 1538 1.5 mrg "VECTOR_MEM_VSX_P (<MODE>mode) && TARGET_ALLOW_MOVMISALIGN" 1539 1.1 mrg { 1540 1.5 mrg rs6000_emit_move (operands[0], operands[1], <MODE>mode); 1541 1.5 mrg DONE; 1542 1.5 mrg }) 1543 1.5 mrg 1544 1.10 mrg ;; Vector shift right in bits. Currently supported ony for shift 1545 1.10 mrg ;; amounts that can be expressed as byte shifts (divisible by 8). 1546 1.10 mrg ;; General shift amounts can be supported using vsro + vsr. We're 1547 1.14 mrg ;; not expecting to see these yet (the vectorizer currently 1548 1.1 mrg ;; generates only shifts by a whole number of vector elements). 1549 1.1 mrg ;; Note that the vec_shr operation is actually defined as 1550 1.1 mrg ;; 'shift toward element 0' so is a shr for LE and shl for BE. 1551 1.1 mrg (define_expand "vec_shr_<mode>" 1552 1.5 mrg [(match_operand:VEC_L 0 "vlogical_operand") 1553 1.1 mrg (match_operand:VEC_L 1 "vlogical_operand") 1554 1.1 mrg (match_operand:QI 2 "reg_or_short_operand")] 1555 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 1556 1.1 mrg { 1557 1.1 mrg rtx bitshift = operands[2]; 1558 1.1 mrg rtx shift; 1559 1.1 mrg rtx insn; 1560 1.1 mrg rtx zero_reg, op1, op2; 1561 1.5 mrg HOST_WIDE_INT bitshift_val; 1562 1.5 mrg HOST_WIDE_INT byteshift_val; 1563 1.5 mrg 1564 1.5 mrg if (! CONSTANT_P (bitshift)) 1565 1.5 mrg FAIL; 1566 1.12 mrg bitshift_val = INTVAL (bitshift); 1567 1.12 mrg if (bitshift_val & 0x7) 1568 1.5 mrg FAIL; 1569 1.5 mrg byteshift_val = (bitshift_val >> 3); 1570 1.1 mrg zero_reg = gen_reg_rtx (<MODE>mode); 1571 1.1 mrg emit_move_insn (zero_reg, CONST0_RTX (<MODE>mode)); 1572 1.1 mrg if (!BYTES_BIG_ENDIAN) 1573 1.5 mrg { 1574 1.5 mrg /* Note, byteshift_val can be 0! */ 1575 1.1 mrg byteshift_val = -byteshift_val & 15; 1576 1.1 mrg op1 = zero_reg; 1577 1.1 mrg op2 = operands[1]; 1578 1.1 mrg } 1579 1.1 mrg else 1580 1.5 mrg { 1581 1.1 mrg op1 = operands[1]; 1582 1.1 mrg op2 = zero_reg; 1583 1.1 mrg } 1584 1.1 mrg 1585 1.5 mrg if (TARGET_VSX && (byteshift_val & 0x3) == 0) 1586 1.1 mrg { 1587 1.1 mrg shift = gen_rtx_CONST_INT (QImode, byteshift_val >> 2); 1588 1.1 mrg insn = gen_vsx_xxsldwi_<mode> (operands[0], op1, op2, shift); 1589 1.1 mrg } 1590 1.10 mrg else 1591 1.1 mrg { 1592 1.1 mrg shift = gen_rtx_CONST_INT (QImode, byteshift_val); 1593 1.1 mrg insn = gen_altivec_vsldoi_<mode> (operands[0], op1, op2, shift); 1594 1.10 mrg } 1595 1.10 mrg 1596 1.10 mrg emit_insn (insn); 1597 1.3 mrg DONE; 1598 1.1 mrg }) 1599 1.1 mrg 1600 1.14 mrg ;; Expanders for rotate each element in a vector 1601 1.14 mrg (define_expand "vrotl<mode>3" 1602 1.14 mrg [(set (match_operand:VEC_I 0 "vint_operand") 1603 1.14 mrg (rotate:VEC_I (match_operand:VEC_I 1 "vint_operand") 1604 1.14 mrg (match_operand:VEC_I 2 "vint_operand")))] 1605 1.14 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 1606 1.14 mrg "") 1607 1.14 mrg 1608 1.14 mrg (define_expand "vrotlv1ti3" 1609 1.14 mrg [(set (match_operand:V1TI 0 "vsx_register_operand" "=v") 1610 1.14 mrg (rotate:V1TI (match_operand:V1TI 1 "vsx_register_operand" "v") 1611 1.14 mrg (match_operand:V1TI 2 "vsx_register_operand" "v")))] 1612 1.14 mrg "TARGET_POWER10" 1613 1.14 mrg { 1614 1.12 mrg /* Shift amount in needs to be put in bits[57:63] of 128-bit operand2. */ 1615 1.12 mrg rtx tmp = gen_reg_rtx (V1TImode); 1616 1.12 mrg 1617 1.12 mrg emit_insn (gen_xxswapd_v1ti (tmp, operands[2])); 1618 1.12 mrg emit_insn (gen_altivec_vrlq (operands[0], operands[1], tmp)); 1619 1.12 mrg DONE; 1620 1.12 mrg }) 1621 1.12 mrg 1622 1.12 mrg ;; Expanders for rotatert to make use of vrotl 1623 1.12 mrg (define_expand "vrotr<mode>3" 1624 1.12 mrg [(set (match_operand:VEC_I 0 "vint_operand") 1625 1.12 mrg (rotatert:VEC_I (match_operand:VEC_I 1 "vint_operand") 1626 1.12 mrg (match_operand:VEC_I 2 "vint_operand")))] 1627 1.1 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 1628 1.1 mrg { 1629 1.10 mrg rtx rot_count = gen_reg_rtx (<MODE>mode); 1630 1.10 mrg emit_insn (gen_neg<mode>2 (rot_count, operands[2])); 1631 1.10 mrg emit_insn (gen_vrotl<mode>3 (operands[0], operands[1], rot_count)); 1632 1.3 mrg DONE; 1633 1.1 mrg }) 1634 1.1 mrg 1635 1.14 mrg ;; Expanders for arithmetic shift left on each vector element 1636 1.14 mrg (define_expand "vashl<mode>3" 1637 1.14 mrg [(set (match_operand:VEC_I 0 "vint_operand") 1638 1.14 mrg (ashift:VEC_I (match_operand:VEC_I 1 "vint_operand") 1639 1.14 mrg (match_operand:VEC_I 2 "vint_operand")))] 1640 1.14 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 1641 1.14 mrg "") 1642 1.14 mrg 1643 1.14 mrg ;; No immediate version of this 128-bit instruction 1644 1.14 mrg (define_expand "vashl<mode>3" 1645 1.14 mrg [(set (match_operand:VEC_TI 0 "vsx_register_operand" "=v") 1646 1.14 mrg (ashift:VEC_TI (match_operand:VEC_TI 1 "vsx_register_operand") 1647 1.14 mrg (match_operand:VEC_TI 2 "vsx_register_operand")))] 1648 1.14 mrg "TARGET_POWER10" 1649 1.14 mrg { 1650 1.1 mrg /* Shift amount in needs to be put in bits[57:63] of 128-bit operand2. */ 1651 1.1 mrg rtx tmp = gen_reg_rtx (<MODE>mode); 1652 1.10 mrg 1653 1.10 mrg emit_insn (gen_xxswapd_v1ti (tmp, operands[2])); 1654 1.10 mrg emit_insn(gen_altivec_vslq_<mode> (operands[0], operands[1], tmp)); 1655 1.3 mrg DONE; 1656 1.1 mrg }) 1657 1.1 mrg 1658 1.14 mrg ;; Expanders for logical shift right on each vector element 1659 1.14 mrg (define_expand "vlshr<mode>3" 1660 1.14 mrg [(set (match_operand:VEC_I 0 "vint_operand") 1661 1.14 mrg (lshiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand") 1662 1.14 mrg (match_operand:VEC_I 2 "vint_operand")))] 1663 1.14 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 1664 1.14 mrg "") 1665 1.14 mrg 1666 1.14 mrg ;; No immediate version of this 128-bit instruction 1667 1.14 mrg (define_expand "vlshr<mode>3" 1668 1.14 mrg [(set (match_operand:VEC_TI 0 "vsx_register_operand" "=v") 1669 1.14 mrg (lshiftrt:VEC_TI (match_operand:VEC_TI 1 "vsx_register_operand") 1670 1.14 mrg (match_operand:VEC_TI 2 "vsx_register_operand")))] 1671 1.14 mrg "TARGET_POWER10" 1672 1.14 mrg { 1673 1.1 mrg /* Shift amount in needs to be put into bits[57:63] of 128-bit operand2. */ 1674 1.1 mrg rtx tmp = gen_reg_rtx (<MODE>mode); 1675 1.10 mrg 1676 1.10 mrg emit_insn (gen_xxswapd_v1ti (tmp, operands[2])); 1677 1.10 mrg emit_insn(gen_altivec_vsrq_<mode> (operands[0], operands[1], tmp)); 1678 1.3 mrg DONE; 1679 1.3 mrg }) 1680 1.14 mrg 1681 1.14 mrg ;; Expanders for arithmetic shift right on each vector element 1682 1.14 mrg (define_expand "vashr<mode>3" 1683 1.14 mrg [(set (match_operand:VEC_I 0 "vint_operand") 1684 1.14 mrg (ashiftrt:VEC_I (match_operand:VEC_I 1 "vint_operand") 1685 1.14 mrg (match_operand:VEC_I 2 "vint_operand")))] 1686 1.14 mrg "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)" 1687 1.14 mrg "") 1688 1.14 mrg 1689 1.14 mrg ;; No immediate version of this 128-bit instruction 1690 1.14 mrg (define_expand "vashrv1ti3" 1691 1.14 mrg [(set (match_operand:V1TI 0 "vsx_register_operand" "=v") 1692 1.14 mrg (ashiftrt:V1TI (match_operand:V1TI 1 "vsx_register_operand" "v") 1693 1.14 mrg (match_operand:V1TI 2 "vsx_register_operand" "v")))] 1694 1.14 mrg "TARGET_POWER10" 1695 1.14 mrg { 1696 1.3 mrg /* Shift amount in needs to be put into bits[57:63] of 128-bit operand2. */ 1697 1.3 mrg rtx tmp = gen_reg_rtx (V1TImode); 1698 1.7 mrg 1699 1.3 mrg emit_insn (gen_xxswapd_v1ti (tmp, operands[2])); 1700 1.7 mrg emit_insn (gen_altivec_vsraq (operands[0], operands[1], tmp)); 1701 1.3 mrg DONE; 1702 1.3 mrg }) 1703 1.3 mrg 1704 1.3 mrg 1706 1.7 mrg ;; Vector reduction expanders for VSX 1707 1.10 mrg ; The (VEC_reduc:... 1708 1.10 mrg ; (op1) 1709 1.7 mrg ; (unspec:... [(const_int 0)] UNSPEC_REDUC)) 1710 1.7 mrg ; 1711 1.7 mrg ; is to allow us to use a code iterator, but not completely list all of the 1712 1.7 mrg ; vector rotates, etc. to prevent canonicalization 1713 1.7 mrg 1714 1.7 mrg 1715 1.7 mrg (define_expand "reduc_<VEC_reduc:VEC_reduc_name>_scal_<VEC_F:mode>" 1716 1.7 mrg [(match_operand:<VEC_base> 0 "register_operand") 1717 1.7 mrg (VEC_reduc:VEC_F (match_operand:VEC_F 1 "vfloat_operand") 1718 1.7 mrg (unspec:VEC_F [(const_int 0)] UNSPEC_REDUC))] 1719 1.7 mrg "VECTOR_UNIT_VSX_P (<VEC_F:MODE>mode)" 1720 1.7 mrg { 1721 rtx vec = gen_reg_rtx (<VEC_F:MODE>mode); 1722 rtx elt = BYTES_BIG_ENDIAN 1723 ? gen_int_mode (GET_MODE_NUNITS (<VEC_F:MODE>mode) - 1, QImode) 1724 : const0_rtx; 1725 emit_insn (gen_vsx_reduc_<VEC_reduc:VEC_reduc_name>_<VEC_F:mode> (vec, 1726 operand1)); 1727 emit_insn (gen_vsx_extract_<VEC_F:mode> (operand0, vec, elt)); 1728 DONE; 1729 }) 1730