1;; PowerPC paired single and double hummer description 2;; Copyright (C) 2007-2014 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 "paired_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 "paired_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 "paired_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 "paired_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 "paired_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 "paired_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_expand "vec_perm_constv2sf" 317 [(match_operand:V2SF 0 "gpc_reg_operand" "") 318 (match_operand:V2SF 1 "gpc_reg_operand" "") 319 (match_operand:V2SF 2 "gpc_reg_operand" "") 320 (match_operand:V2SI 3 "" "")] 321 "TARGET_PAIRED_FLOAT" 322{ 323 if (rs6000_expand_vec_perm_const (operands)) 324 DONE; 325 else 326 FAIL; 327}) 328 329(define_insn "paired_sum0" 330 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 331 (vec_concat:V2SF (plus:SF (vec_select:SF 332 (match_operand:V2SF 1 "gpc_reg_operand" "f") 333 (parallel [(const_int 0)])) 334 (vec_select:SF 335 (match_operand:V2SF 2 "gpc_reg_operand" "f") 336 (parallel [(const_int 1)]))) 337 (vec_select:SF 338 (match_operand:V2SF 3 "gpc_reg_operand" "f") 339 (parallel [(const_int 1)]))))] 340 "TARGET_PAIRED_FLOAT" 341 "ps_sum0 %0,%1,%2,%3" 342 [(set_attr "type" "fp")]) 343 344(define_insn "paired_sum1" 345 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 346 (vec_concat:V2SF (vec_select:SF 347 (match_operand:V2SF 2 "gpc_reg_operand" "f") 348 (parallel [(const_int 1)])) 349 (plus:SF (vec_select:SF 350 (match_operand:V2SF 1 "gpc_reg_operand" "f") 351 (parallel [(const_int 0)])) 352 (vec_select:SF 353 (match_operand:V2SF 3 "gpc_reg_operand" "f") 354 (parallel [(const_int 1)])))))] 355 "TARGET_PAIRED_FLOAT" 356 "ps_sum1 %0,%1,%2,%3" 357 [(set_attr "type" "fp")]) 358 359(define_insn "paired_muls0" 360 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 361 (mult:V2SF (match_operand:V2SF 2 "gpc_reg_operand" "f") 362 (vec_duplicate:V2SF 363 (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") 364 (parallel [(const_int 0)])))))] 365 "TARGET_PAIRED_FLOAT" 366 "ps_muls0 %0, %1, %2" 367 [(set_attr "type" "fp")]) 368 369 370(define_insn "paired_muls1" 371 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 372 (mult:V2SF (match_operand:V2SF 2 "gpc_reg_operand" "f") 373 (vec_duplicate:V2SF 374 (vec_select:SF (match_operand:V2SF 1 "gpc_reg_operand" "f") 375 (parallel [(const_int 1)])))))] 376 "TARGET_PAIRED_FLOAT" 377 "ps_muls1 %0, %1, %2" 378 [(set_attr "type" "fp")]) 379 380(define_expand "vec_initv2sf" 381 [(match_operand:V2SF 0 "gpc_reg_operand" "=f") 382 (match_operand 1 "" "")] 383 "TARGET_PAIRED_FLOAT" 384{ 385 paired_expand_vector_init (operands[0], operands[1]); 386 DONE; 387}) 388 389(define_insn "*vconcatsf" 390 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 391 (vec_concat:V2SF 392 (match_operand:SF 1 "gpc_reg_operand" "f") 393 (match_operand:SF 2 "gpc_reg_operand" "f")))] 394 "TARGET_PAIRED_FLOAT" 395 "ps_merge00 %0, %1, %2" 396 [(set_attr "type" "fp")]) 397 398(define_expand "sminv2sf3" 399 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 400 (smin: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[2], operands[1], CONST0_RTX (SFmode))); 408 DONE; 409}) 410 411(define_expand "smaxv2sf3" 412 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 413 (smax:V2SF (match_operand:V2SF 1 "gpc_reg_operand" "f") 414 (match_operand:V2SF 2 "gpc_reg_operand" "f")))] 415 "TARGET_PAIRED_FLOAT" 416{ 417 rtx tmp = gen_reg_rtx (V2SFmode); 418 419 emit_insn (gen_subv2sf3 (tmp, operands[1], operands[2])); 420 emit_insn (gen_selv2sf4 (operands[0], tmp, operands[1], operands[2], CONST0_RTX (SFmode))); 421 DONE; 422}) 423 424(define_expand "reduc_smax_v2sf" 425 [(match_operand:V2SF 0 "gpc_reg_operand" "=f") 426 (match_operand:V2SF 1 "gpc_reg_operand" "f")] 427 "TARGET_PAIRED_FLOAT" 428{ 429 rtx tmp_swap = gen_reg_rtx (V2SFmode); 430 rtx tmp = gen_reg_rtx (V2SFmode); 431 432 emit_insn (gen_paired_merge10 (tmp_swap, operands[1], operands[1])); 433 emit_insn (gen_subv2sf3 (tmp, operands[1], tmp_swap)); 434 emit_insn (gen_selv2sf4 (operands[0], tmp, operands[1], tmp_swap, CONST0_RTX (SFmode))); 435 436 DONE; 437}) 438 439(define_expand "reduc_smin_v2sf" 440 [(match_operand:V2SF 0 "gpc_reg_operand" "=f") 441 (match_operand:V2SF 1 "gpc_reg_operand" "f")] 442 "TARGET_PAIRED_FLOAT" 443{ 444 rtx tmp_swap = gen_reg_rtx (V2SFmode); 445 rtx tmp = gen_reg_rtx (V2SFmode); 446 447 emit_insn (gen_paired_merge10 (tmp_swap, operands[1], operands[1])); 448 emit_insn (gen_subv2sf3 (tmp, operands[1], tmp_swap)); 449 emit_insn (gen_selv2sf4 (operands[0], tmp, tmp_swap, operands[1], CONST0_RTX (SFmode))); 450 451 DONE; 452}) 453 454(define_expand "reduc_splus_v2sf" 455 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 456 (match_operand:V2SF 1 "gpc_reg_operand" "f"))] 457 "TARGET_PAIRED_FLOAT" 458 " 459{ 460 emit_insn (gen_paired_sum1 (operands[0], operands[1], operands[1], operands[1])); 461 DONE; 462}") 463 464(define_expand "movmisalignv2sf" 465 [(set (match_operand:V2SF 0 "nonimmediate_operand" "") 466 (match_operand:V2SF 1 "any_operand" ""))] 467 "TARGET_PAIRED_FLOAT" 468{ 469 paired_expand_vector_move (operands); 470 DONE; 471}) 472 473(define_expand "vcondv2sfv2sf" 474 [(set (match_operand:V2SF 0 "gpc_reg_operand" "=f") 475 (if_then_else:V2SF 476 (match_operator 3 "gpc_reg_operand" 477 [(match_operand:V2SF 4 "gpc_reg_operand" "f") 478 (match_operand:V2SF 5 "gpc_reg_operand" "f")]) 479 (match_operand:V2SF 1 "gpc_reg_operand" "f") 480 (match_operand:V2SF 2 "gpc_reg_operand" "f")))] 481 "TARGET_PAIRED_FLOAT && flag_unsafe_math_optimizations" 482{ 483 if (paired_emit_vector_cond_expr (operands[0], operands[1], operands[2], 484 operands[3], operands[4], operands[5])) 485 DONE; 486 else 487 FAIL; 488}) 489