1;; PowerPC paired single and double hummer description 2;; Copyright (C) 2007-2018 Free Software Foundation, Inc. 3;; Contributed by David Edelsohn <edelsohn@gnu.org> and Revital Eres 4;; <eres@il.ibm.com> 5 6;; This file is part of GCC. 7 8;; GCC is free software; you can redistribute it and/or modify it 9;; under the terms of the GNU General Public License as published 10;; by the Free Software Foundation; either version 3, or (at your 11;; option) any later version. 12 13;; GCC is distributed in the hope that it will be useful, but WITHOUT 14;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 16;; License for more details. 17;; 18;; You should have received a copy of the GNU General Public License 19;; along with this program; see the file COPYING3. If not see 20;; <http://www.gnu.org/licenses/>. 21 22(define_c_enum "unspec" 23 [UNSPEC_INTERHI_V2SF 24 UNSPEC_INTERLO_V2SF 25 UNSPEC_EXTEVEN_V2SF 26 UNSPEC_EXTODD_V2SF 27 ]) 28 29(define_insn "negv2sf2" 30 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 31 (neg:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))] 32 "TARGET_PAIRED_FLOAT" 33 "ps_neg %0,%1" 34 [(set_attr "type" "fp")]) 35 36(define_insn "sqrtv2sf2" 37 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 38 (sqrt:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))] 39 "TARGET_PAIRED_FLOAT" 40 "ps_rsqrte %0,%1" 41 [(set_attr "type" "fp")]) 42 43(define_insn "absv2sf2" 44 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 45 (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f")))] 46 "TARGET_PAIRED_FLOAT" 47 "ps_abs %0,%1" 48 [(set_attr "type" "fp")]) 49 50(define_insn "nabsv2sf2" 51 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 52 (neg:V2SF (abs:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f"))))] 53 "TARGET_PAIRED_FLOAT" 54 "ps_nabs %0,%1" 55 [(set_attr "type" "fp")]) 56 57(define_insn "addv2sf3" 58 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 59 (plus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f") 60 (match_operand:V2SF 2 "gpc_reg_operand" "f")))] 61 "TARGET_PAIRED_FLOAT" 62 "ps_add %0,%1,%2" 63 [(set_attr "type" "fp")]) 64 65(define_insn "subv2sf3" 66 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 67 (minus:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f") 68 (match_operand:V2SF 2 "gpc_reg_operand" "f")))] 69 "TARGET_PAIRED_FLOAT" 70 "ps_sub %0,%1,%2" 71 [(set_attr "type" "fp")]) 72 73(define_insn "mulv2sf3" 74 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 75 (mult:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "%f") 76 (match_operand:V2SF 2 "gpc_reg_operand" "f")))] 77 "TARGET_PAIRED_FLOAT" 78 "ps_mul %0,%1,%2" 79 [(set_attr "type" "fp")]) 80 81(define_insn "resv2sf2" 82 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 83 (unspec:V2SF [(match_operand:V2SF 1 "gpc_reg_operand" "f")] UNSPEC_FRES))] 84 "TARGET_PAIRED_FLOAT && flag_finite_math_only" 85 "ps_res %0,%1" 86 [(set_attr "type" "fp")]) 87 88(define_insn "divv2sf3" 89 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 90 (div:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f") 91 (match_operand:V2SF 2 "gpc_reg_operand" "f")))] 92 "TARGET_PAIRED_FLOAT" 93 "ps_div %0,%1,%2" 94 [(set_attr "type" "sdiv")]) 95 96(define_insn "paired_madds0" 97 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 98 (vec_concat:V2SF 99 (fma:SF 100 (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") 101 (parallel [(const_int 0)])) 102 (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f") 103 (parallel [(const_int 0)])) 104 (vec_select:SF (match_operand:V2SF 3 "gpc_reg_operand" "f") 105 (parallel [(const_int 0)]))) 106 (fma:SF 107 (vec_select:SF (match_dup 1) 108 (parallel [(const_int 1)])) 109 (vec_select:SF (match_dup 2) 110 (parallel [(const_int 0)])) 111 (vec_select:SF (match_dup 3) 112 (parallel [(const_int 1)])))))] 113 "TARGET_PAIRED_FLOAT" 114 "ps_madds0 %0,%1,%2,%3" 115 [(set_attr "type" "fp")]) 116 117(define_insn "paired_madds1" 118 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 119 (vec_concat:V2SF 120 (fma:SF 121 (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") 122 (parallel [(const_int 0)])) 123 (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f") 124 (parallel [(const_int 1)])) 125 (vec_select:SF (match_operand:V2SF 3 "gpc_reg_operand" "f") 126 (parallel [(const_int 0)]))) 127 (fma:SF 128 (vec_select:SF (match_dup 1) 129 (parallel [(const_int 1)])) 130 (vec_select:SF (match_dup 2) 131 (parallel [(const_int 1)])) 132 (vec_select:SF (match_dup 3) 133 (parallel [(const_int 1)])))))] 134 "TARGET_PAIRED_FLOAT" 135 "ps_madds1 %0,%1,%2,%3" 136 [(set_attr "type" "fp")]) 137 138(define_insn "*paired_madd" 139 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 140 (fma:V2SF 141 (match_operand:V2SF 1 "gpc_reg_operand" "f") 142 (match_operand:V2SF 2 "gpc_reg_operand" "f") 143 (match_operand:V2SF 3 "gpc_reg_operand" "f")))] 144 "TARGET_PAIRED_FLOAT" 145 "ps_madd %0,%1,%2,%3" 146 [(set_attr "type" "fp")]) 147 148(define_insn "*paired_msub" 149 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 150 (fma:V2SF 151 (match_operand:V2SF 1 "gpc_reg_operand" "f") 152 (match_operand:V2SF 2 "gpc_reg_operand" "f") 153 (neg:V2SF (match_operand:V2SF 3 "gpc_reg_operand" "f"))))] 154 "TARGET_PAIRED_FLOAT" 155 "ps_msub %0,%1,%2,%3" 156 [(set_attr "type" "fp")]) 157 158(define_insn "*paired_nmadd" 159 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 160 (neg:V2SF 161 (fma:V2SF 162 (match_operand:V2SF 1 "gpc_reg_operand" "f") 163 (match_operand:V2SF 2 "gpc_reg_operand" "f") 164 (match_operand:V2SF 3 "gpc_reg_operand" "f"))))] 165 "TARGET_PAIRED_FLOAT" 166 "ps_nmadd %0,%1,%2,%3" 167 [(set_attr "type" "fp")]) 168 169(define_insn "*paired_nmsub" 170 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 171 (neg:V2SF 172 (fma:V2SF 173 (match_operand:V2SF 1 "gpc_reg_operand" "f") 174 (match_operand:V2SF 2 "gpc_reg_operand" "f") 175 (neg:V2SF (match_operand:V2SF 3 "gpc_reg_operand" "f")))))] 176 "TARGET_PAIRED_FLOAT" 177 "ps_nmsub %0,%1,%2,%3" 178 [(set_attr "type" "dmul")]) 179 180(define_insn "selv2sf4" 181 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 182 (vec_concat:V2SF 183 (if_then_else:SF (ge (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") 184 (parallel [(const_int 0)])) 185 (match_operand:SF 4 "zero_fp_constant" "F")) 186 (vec_select:SF (match_operand:V2SF 2 "gpc_reg_operand" "f") 187 (parallel [(const_int 0)])) 188 (vec_select:SF (match_operand:V2SF 3 "gpc_reg_operand" "f") 189 (parallel [(const_int 0)]))) 190 (if_then_else:SF (ge (vec_select:SF (match_dup 1) 191 (parallel [(const_int 1)])) 192 (match_dup 4)) 193 (vec_select:SF (match_dup 2) 194 (parallel [(const_int 1)])) 195 (vec_select:SF (match_dup 3) 196 (parallel [(const_int 1)])))))] 197 198 "TARGET_PAIRED_FLOAT" 199 "ps_sel %0,%1,%2,%3" 200 [(set_attr "type" "fp")]) 201 202(define_insn "*movv2sf_paired" 203 [(set (match_operand:V2SF 0 "nonimmediate_operand" "=Z,f,f,Y,r,r,f") 204 (match_operand:V2SF 1 "input_operand" "f,Z,f,r,Y,r,W"))] 205 "TARGET_PAIRED_FLOAT 206 && (register_operand (operands[0], V2SFmode) 207 || register_operand (operands[1], V2SFmode))" 208{ 209 switch (which_alternative) 210 { 211 case 0: return "psq_stx %1,%y0,0,0"; 212 case 1: return "psq_lx %0,%y1,0,0"; 213 case 2: return "ps_mr %0,%1"; 214 case 3: return "#"; 215 case 4: return "#"; 216 case 5: return "#"; 217 case 6: return "#"; 218 default: gcc_unreachable (); 219 } 220} 221 [(set_attr "type" "fpstore,fpload,fp,*,*,*,*")]) 222 223(define_insn "paired_stx" 224 [(set (match_operand:V2SF 0 "memory_operand" "=Z") 225 (match_operand:V2SF 1 "gpc_reg_operand" "f"))] 226 "TARGET_PAIRED_FLOAT" 227 "psq_stx %1,%y0,0,0" 228 [(set_attr "type" "fpstore")]) 229 230(define_insn "paired_lx" 231 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 232 (match_operand:V2SF 1 "memory_operand" "Z"))] 233 "TARGET_PAIRED_FLOAT" 234 "psq_lx %0,%y1,0,0" 235 [(set_attr "type" "fpload")]) 236 237 238(define_split 239 [(set (match_operand:V2SF 0 "nonimmediate_operand" "") 240 (match_operand:V2SF 1 "input_operand" ""))] 241 "TARGET_PAIRED_FLOAT && reload_completed 242 && gpr_or_gpr_p (operands[0], operands[1])" 243 [(pc)] 244 { 245 rs6000_split_multireg_move (operands[0], operands[1]); DONE; 246 }) 247 248(define_insn "paired_cmpu0" 249 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 250 (compare:CCFP (vec_select:SF 251 (match_operand:V2SF 1 "gpc_reg_operand" "f") 252 (parallel [(const_int 0)])) 253 (vec_select:SF 254 (match_operand:V2SF 2 "gpc_reg_operand" "f") 255 (parallel [(const_int 0)]))))] 256 "TARGET_PAIRED_FLOAT" 257 "ps_cmpu0 %0,%1,%2" 258 [(set_attr "type" "fpcompare")]) 259 260(define_insn "paired_cmpu1" 261 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 262 (compare:CCFP (vec_select:SF 263 (match_operand:V2SF 1 "gpc_reg_operand" "f") 264 (parallel [(const_int 1)])) 265 (vec_select:SF 266 (match_operand:V2SF 2 "gpc_reg_operand" "f") 267 (parallel [(const_int 1)]))))] 268 "TARGET_PAIRED_FLOAT" 269 "ps_cmpu1 %0,%1,%2" 270 [(set_attr "type" "fpcompare")]) 271 272(define_insn "paired_merge00" 273 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 274 (vec_select:V2SF 275 (vec_concat:V4SF 276 (match_operand:V2SF 1 "gpc_reg_operand" "f") 277 (match_operand:V2SF 2 "gpc_reg_operand" "f")) 278 (parallel [(const_int 0) (const_int 2)])))] 279 "TARGET_PAIRED_FLOAT" 280 "ps_merge00 %0, %1, %2" 281 [(set_attr "type" "fp")]) 282 283(define_insn "paired_merge01" 284 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 285 (vec_select:V2SF 286 (vec_concat:V4SF 287 (match_operand:V2SF 1 "gpc_reg_operand" "f") 288 (match_operand:V2SF 2 "gpc_reg_operand" "f")) 289 (parallel [(const_int 0) (const_int 3)])))] 290 "TARGET_PAIRED_FLOAT" 291 "ps_merge01 %0, %1, %2" 292 [(set_attr "type" "fp")]) 293 294(define_insn "paired_merge10" 295 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 296 (vec_select:V2SF 297 (vec_concat:V4SF 298 (match_operand:V2SF 1 "gpc_reg_operand" "f") 299 (match_operand:V2SF 2 "gpc_reg_operand" "f")) 300 (parallel [(const_int 1) (const_int 2)])))] 301 "TARGET_PAIRED_FLOAT" 302 "ps_merge10 %0, %1, %2" 303 [(set_attr "type" "fp")]) 304 305(define_insn "paired_merge11" 306 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 307 (vec_select:V2SF 308 (vec_concat:V4SF 309 (match_operand:V2SF 1 "gpc_reg_operand" "f") 310 (match_operand:V2SF 2 "gpc_reg_operand" "f")) 311 (parallel [(const_int 1) (const_int 3)])))] 312 "TARGET_PAIRED_FLOAT" 313 "ps_merge11 %0, %1, %2" 314 [(set_attr "type" "fp")]) 315 316(define_insn "paired_sum0" 317 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 318 (vec_concat:V2SF (plus:SF (vec_select:SF 319 (match_operand:V2SF 1 "gpc_reg_operand" "f") 320 (parallel [(const_int 0)])) 321 (vec_select:SF 322 (match_operand:V2SF 2 "gpc_reg_operand" "f") 323 (parallel [(const_int 1)]))) 324 (vec_select:SF 325 (match_operand:V2SF 3 "gpc_reg_operand" "f") 326 (parallel [(const_int 1)]))))] 327 "TARGET_PAIRED_FLOAT" 328 "ps_sum0 %0,%1,%2,%3" 329 [(set_attr "type" "fp")]) 330 331(define_insn "paired_sum1" 332 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 333 (vec_concat:V2SF (vec_select:SF 334 (match_operand:V2SF 2 "gpc_reg_operand" "f") 335 (parallel [(const_int 1)])) 336 (plus:SF (vec_select:SF 337 (match_operand:V2SF 1 "gpc_reg_operand" "f") 338 (parallel [(const_int 0)])) 339 (vec_select:SF 340 (match_operand:V2SF 3 "gpc_reg_operand" "f") 341 (parallel [(const_int 1)])))))] 342 "TARGET_PAIRED_FLOAT" 343 "ps_sum1 %0,%1,%2,%3" 344 [(set_attr "type" "fp")]) 345 346(define_insn "paired_muls0" 347 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 348 (mult:V2SF (match_operand:V2SF 2 "gpc_reg_operand" "f") 349 (vec_duplicate:V2SF 350 (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") 351 (parallel [(const_int 0)])))))] 352 "TARGET_PAIRED_FLOAT" 353 "ps_muls0 %0, %1, %2" 354 [(set_attr "type" "fp")]) 355 356 357(define_insn "paired_muls1" 358 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 359 (mult:V2SF (match_operand:V2SF 2 "gpc_reg_operand" "f") 360 (vec_duplicate:V2SF 361 (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") 362 (parallel [(const_int 1)])))))] 363 "TARGET_PAIRED_FLOAT" 364 "ps_muls1 %0, %1, %2" 365 [(set_attr "type" "fp")]) 366 367(define_expand "vec_initv2sfsf" 368 [(match_operand:V2SF 0 "gpc_reg_operand" "=f") 369 (match_operand 1 "" "")] 370 "TARGET_PAIRED_FLOAT" 371{ 372 paired_expand_vector_init (operands[0], operands[1]); 373 DONE; 374}) 375 376(define_insn "*vconcatsf" 377 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 378 (vec_concat:V2SF 379 (match_operand:SF 1 "gpc_reg_operand" "f") 380 (match_operand:SF 2 "gpc_reg_operand" "f")))] 381 "TARGET_PAIRED_FLOAT" 382 "ps_merge00 %0, %1, %2" 383 [(set_attr "type" "fp")]) 384 385(define_expand "sminv2sf3" 386 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 387 (smin:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f") 388 (match_operand:V2SF 2 "gpc_reg_operand" "f")))] 389 "TARGET_PAIRED_FLOAT" 390{ 391 rtx tmp = gen_reg_rtx (V2SFmode); 392 393 emit_insn (gen_subv2sf3 (tmp, operands[1], operands[2])); 394 emit_insn (gen_selv2sf4 (operands[0], tmp, operands[2], operands[1], CONST0_RTX (SFmode))); 395 DONE; 396}) 397 398(define_expand "smaxv2sf3" 399 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 400 (smax:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f") 401 (match_operand:V2SF 2 "gpc_reg_operand" "f")))] 402 "TARGET_PAIRED_FLOAT" 403{ 404 rtx tmp = gen_reg_rtx (V2SFmode); 405 406 emit_insn (gen_subv2sf3 (tmp, operands[1], operands[2])); 407 emit_insn (gen_selv2sf4 (operands[0], tmp, operands[1], operands[2], CONST0_RTX (SFmode))); 408 DONE; 409}) 410 411(define_expand "reduc_smax_scal_v2sf" 412 [(match_operand:SF 0 "gpc_reg_operand" "=f") 413 (match_operand:V2SF 1 "gpc_reg_operand" "f")] 414 "TARGET_PAIRED_FLOAT" 415{ 416 rtx tmp_swap = gen_reg_rtx (V2SFmode); 417 rtx tmp = gen_reg_rtx (V2SFmode); 418 rtx vec_res = gen_reg_rtx (V2SFmode); 419 rtx di_res = gen_reg_rtx (DImode); 420 421 emit_insn (gen_paired_merge10 (tmp_swap, operands[1], operands[1])); 422 emit_insn (gen_subv2sf3 (tmp, operands[1], tmp_swap)); 423 emit_insn (gen_selv2sf4 (vec_res, tmp, operands[1], tmp_swap, 424 CONST0_RTX (SFmode))); 425 emit_move_insn (di_res, simplify_gen_subreg (DImode, vec_res, V2SFmode, 0)); 426 emit_move_insn (operands[0], simplify_gen_subreg (SFmode, di_res, DImode, 427 BYTES_BIG_ENDIAN ? 4 : 0)); 428 429 DONE; 430}) 431 432(define_expand "reduc_smin_scal_v2sf" 433 [(match_operand:SF 0 "gpc_reg_operand" "=f") 434 (match_operand:V2SF 1 "gpc_reg_operand" "f")] 435 "TARGET_PAIRED_FLOAT" 436{ 437 rtx tmp_swap = gen_reg_rtx (V2SFmode); 438 rtx tmp = gen_reg_rtx (V2SFmode); 439 rtx vec_res = gen_reg_rtx (V2SFmode); 440 rtx di_res = gen_reg_rtx (DImode); 441 442 emit_insn (gen_paired_merge10 (tmp_swap, operands[1], operands[1])); 443 emit_insn (gen_subv2sf3 (tmp, operands[1], tmp_swap)); 444 emit_insn (gen_selv2sf4 (vec_res, tmp, tmp_swap, operands[1], 445 CONST0_RTX (SFmode))); 446 emit_move_insn (di_res, simplify_gen_subreg (DImode, vec_res, V2SFmode, 0)); 447 emit_move_insn (operands[0], simplify_gen_subreg (SFmode, di_res, DImode, 448 BYTES_BIG_ENDIAN ? 4 : 0)); 449 450 DONE; 451}) 452 453(define_expand "reduc_plus_scal_v2sf" 454 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 455 (match_operand:V2SF 1 "gpc_reg_operand" "f"))] 456 "TARGET_PAIRED_FLOAT" 457{ 458 rtx vec_res = gen_reg_rtx (V2SFmode); 459 rtx di_res = gen_reg_rtx (DImode); 460 461 emit_insn (gen_paired_sum1 (vec_res, operands[1], operands[1], operands[1])); 462 emit_move_insn (di_res, simplify_gen_subreg (DImode, vec_res, V2SFmode, 0)); 463 emit_move_insn (operands[0], simplify_gen_subreg (SFmode, di_res, DImode, 464 BYTES_BIG_ENDIAN ? 4 : 0)); 465 DONE; 466}) 467 468(define_expand "movmisalignv2sf" 469 [(set (match_operand:V2SF 0 "nonimmediate_operand" "") 470 (match_operand:V2SF 1 "any_operand" ""))] 471 "TARGET_PAIRED_FLOAT" 472{ 473 paired_expand_vector_move (operands); 474 DONE; 475}) 476 477(define_expand "vcondv2sfv2sf" 478 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 479 (if_then_else:V2SF 480 (match_operator 3 "gpc_reg_operand" 481 [(match_operand:V2SF 4 "gpc_reg_operand" "f") 482 (match_operand:V2SF 5 "gpc_reg_operand" "f")]) 483 (match_operand:V2SF 1 "gpc_reg_operand" "f") 484 (match_operand:V2SF 2 "gpc_reg_operand" "f")))] 485 "TARGET_PAIRED_FLOAT && flag_unsafe_math_optimizations" 486{ 487 if (paired_emit_vector_cond_expr (operands[0], operands[1], operands[2], 488 operands[3], operands[4], operands[5])) 489 DONE; 490 else 491 FAIL; 492}) 493