Mercurial > hg > CbC > CbC_gcc
comparison gcc/config/rs6000/vsx.md @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | 77e2b8dfacca |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 ;; VSX patterns. | 1 ;; VSX patterns. |
2 ;; Copyright (C) 2009 | 2 ;; Copyright (C) 2009, 2010, 2011 |
3 ;; Free Software Foundation, Inc. | 3 ;; Free Software Foundation, Inc. |
4 ;; Contributed by Michael Meissner <meissner@linux.vnet.ibm.com> | 4 ;; Contributed by Michael Meissner <meissner@linux.vnet.ibm.com> |
5 | 5 |
6 ;; This file is part of GCC. | 6 ;; This file is part of GCC. |
7 | 7 |
25 ;; Iterator for the 2 64-bit vector types | 25 ;; Iterator for the 2 64-bit vector types |
26 (define_mode_iterator VSX_D [V2DF V2DI]) | 26 (define_mode_iterator VSX_D [V2DF V2DI]) |
27 | 27 |
28 ;; Iterator for the 2 32-bit vector types | 28 ;; Iterator for the 2 32-bit vector types |
29 (define_mode_iterator VSX_W [V4SF V4SI]) | 29 (define_mode_iterator VSX_W [V4SF V4SI]) |
30 | |
31 ;; Iterator for the DF types | |
32 (define_mode_iterator VSX_DF [V2DF DF]) | |
30 | 33 |
31 ;; Iterator for vector floating point types supported by VSX | 34 ;; Iterator for vector floating point types supported by VSX |
32 (define_mode_iterator VSX_F [V4SF V2DF]) | 35 (define_mode_iterator VSX_F [V4SF V2DF]) |
33 | 36 |
34 ;; Iterator for logical types supported by VSX | 37 ;; Iterator for logical types supported by VSX |
71 (TI "wd")]) | 74 (TI "wd")]) |
72 | 75 |
73 ;; Map the register class used for float<->int conversions | 76 ;; Map the register class used for float<->int conversions |
74 (define_mode_attr VSr2 [(V2DF "wd") | 77 (define_mode_attr VSr2 [(V2DF "wd") |
75 (V4SF "wf") | 78 (V4SF "wf") |
76 (DF "!f#r")]) | 79 (DF "ws")]) |
77 | 80 |
78 (define_mode_attr VSr3 [(V2DF "wa") | 81 (define_mode_attr VSr3 [(V2DF "wa") |
79 (V4SF "wa") | 82 (V4SF "wa") |
80 (DF "!f#r")]) | 83 (DF "ws")]) |
81 | 84 |
82 ;; Map the register class for sp<->dp float conversions, destination | 85 ;; Map the register class for sp<->dp float conversions, destination |
83 (define_mode_attr VSr4 [(SF "ws") | 86 (define_mode_attr VSr4 [(SF "ws") |
84 (DF "f") | 87 (DF "f") |
85 (V2DF "wd") | 88 (V2DF "wd") |
189 (UNSPEC_VSX_CVUXWDP 505) | 192 (UNSPEC_VSX_CVUXWDP 505) |
190 (UNSPEC_VSX_CVSXDSP 506) | 193 (UNSPEC_VSX_CVSXDSP 506) |
191 (UNSPEC_VSX_CVUXDSP 507) | 194 (UNSPEC_VSX_CVUXDSP 507) |
192 (UNSPEC_VSX_CVSPSXDS 508) | 195 (UNSPEC_VSX_CVSPSXDS 508) |
193 (UNSPEC_VSX_CVSPUXDS 509) | 196 (UNSPEC_VSX_CVSPUXDS 509) |
194 (UNSPEC_VSX_MADD 510) | 197 ;; 510-514 deleted |
195 (UNSPEC_VSX_MSUB 511) | |
196 (UNSPEC_VSX_NMADD 512) | |
197 (UNSPEC_VSX_NMSUB 513) | |
198 (UNSPEC_VSX_RSQRTE 514) | |
199 (UNSPEC_VSX_TDIV 515) | 198 (UNSPEC_VSX_TDIV 515) |
200 (UNSPEC_VSX_TSQRT 516) | 199 (UNSPEC_VSX_TSQRT 516) |
201 (UNSPEC_VSX_XXPERMDI 517) | 200 (UNSPEC_VSX_XXPERMDI 517) |
202 (UNSPEC_VSX_SET 518) | 201 (UNSPEC_VSX_SET 518) |
203 (UNSPEC_VSX_ROUND_I 519) | 202 (UNSPEC_VSX_ROUND_I 519) |
307 gcc_unreachable (); | 306 gcc_unreachable (); |
308 } | 307 } |
309 } | 308 } |
310 [(set_attr "type" "vecstore,vecload,vecsimple,*,*,*,vecsimple,*,vecstore,vecload")]) | 309 [(set_attr "type" "vecstore,vecload,vecsimple,*,*,*,vecsimple,*,vecstore,vecload")]) |
311 | 310 |
311 ;; Explicit load/store expanders for the builtin functions | |
312 (define_expand "vsx_load_<mode>" | |
313 [(set (match_operand:VSX_M 0 "vsx_register_operand" "") | |
314 (match_operand:VSX_M 1 "memory_operand" ""))] | |
315 "VECTOR_MEM_VSX_P (<MODE>mode)" | |
316 "") | |
317 | |
318 (define_expand "vsx_store_<mode>" | |
319 [(set (match_operand:VEC_M 0 "memory_operand" "") | |
320 (match_operand:VEC_M 1 "vsx_register_operand" ""))] | |
321 "VECTOR_MEM_VSX_P (<MODE>mode)" | |
322 "") | |
323 | |
312 | 324 |
313 ;; VSX scalar and vector floating point arithmetic instructions | 325 ;; VSX scalar and vector floating point arithmetic instructions |
314 (define_insn "*vsx_add<mode>3" | 326 (define_insn "*vsx_add<mode>3" |
315 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") | 327 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") |
316 (plus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") | 328 (plus:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") |
436 "VECTOR_UNIT_VSX_P (<MODE>mode)" | 448 "VECTOR_UNIT_VSX_P (<MODE>mode)" |
437 "x<VSv>min<VSs> %x0,%x1,%x2" | 449 "x<VSv>min<VSs> %x0,%x1,%x2" |
438 [(set_attr "type" "<VStype_simple>") | 450 [(set_attr "type" "<VStype_simple>") |
439 (set_attr "fp_type" "<VSfptype_simple>")]) | 451 (set_attr "fp_type" "<VSfptype_simple>")]) |
440 | 452 |
453 ;; Special VSX version of smin/smax for single precision floating point. Since | |
454 ;; both numbers are rounded to single precision, we can just use the DP version | |
455 ;; of the instruction. | |
456 | |
457 (define_insn "*vsx_smaxsf3" | |
458 [(set (match_operand:SF 0 "vsx_register_operand" "=f") | |
459 (smax:SF (match_operand:SF 1 "vsx_register_operand" "f") | |
460 (match_operand:SF 2 "vsx_register_operand" "f")))] | |
461 "VECTOR_UNIT_VSX_P (DFmode)" | |
462 "xsmaxdp %x0,%x1,%x2" | |
463 [(set_attr "type" "fp") | |
464 (set_attr "fp_type" "fp_addsub_d")]) | |
465 | |
466 (define_insn "*vsx_sminsf3" | |
467 [(set (match_operand:SF 0 "vsx_register_operand" "=f") | |
468 (smin:SF (match_operand:SF 1 "vsx_register_operand" "f") | |
469 (match_operand:SF 2 "vsx_register_operand" "f")))] | |
470 "VECTOR_UNIT_VSX_P (DFmode)" | |
471 "xsmindp %x0,%x1,%x2" | |
472 [(set_attr "type" "fp") | |
473 (set_attr "fp_type" "fp_addsub_d")]) | |
474 | |
441 (define_insn "*vsx_sqrt<mode>2" | 475 (define_insn "*vsx_sqrt<mode>2" |
442 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") | 476 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") |
443 (sqrt:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))] | 477 (sqrt:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))] |
444 "VECTOR_UNIT_VSX_P (<MODE>mode)" | 478 "VECTOR_UNIT_VSX_P (<MODE>mode)" |
445 "x<VSv>sqrt<VSs> %x0,%x1" | 479 "x<VSv>sqrt<VSs> %x0,%x1" |
446 [(set_attr "type" "<VStype_sqrt>") | 480 [(set_attr "type" "<VStype_sqrt>") |
447 (set_attr "fp_type" "<VSfptype_sqrt>")]) | 481 (set_attr "fp_type" "<VSfptype_sqrt>")]) |
448 | 482 |
449 (define_insn "vsx_rsqrte<mode>2" | 483 (define_insn "*vsx_rsqrte<mode>2" |
450 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") | 484 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") |
451 (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] | 485 (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")] |
452 UNSPEC_VSX_RSQRTE))] | 486 UNSPEC_RSQRT))] |
453 "VECTOR_UNIT_VSX_P (<MODE>mode)" | 487 "VECTOR_UNIT_VSX_P (<MODE>mode)" |
454 "x<VSv>rsqrte<VSs> %x0,%x1" | 488 "x<VSv>rsqrte<VSs> %x0,%x1" |
455 [(set_attr "type" "<VStype_simple>") | 489 [(set_attr "type" "<VStype_simple>") |
456 (set_attr "fp_type" "<VSfptype_simple>")]) | 490 (set_attr "fp_type" "<VSfptype_simple>")]) |
457 | 491 |
490 [(set_attr "type" "<VStype_simple>") | 524 [(set_attr "type" "<VStype_simple>") |
491 (set_attr "fp_type" "<VSfptype_simple>")]) | 525 (set_attr "fp_type" "<VSfptype_simple>")]) |
492 | 526 |
493 ;; Fused vector multiply/add instructions | 527 ;; Fused vector multiply/add instructions |
494 | 528 |
495 ;; Note we have a pattern for the multiply/add operations that uses unspec and | 529 (define_insn "*vsx_fma<mode>4" |
496 ;; does not check -mfused-madd to allow users to use these ops when they know | |
497 ;; they want the fused multiply/add. | |
498 | |
499 (define_expand "vsx_fmadd<mode>4" | |
500 [(set (match_operand:VSX_B 0 "vsx_register_operand" "") | |
501 (plus:VSX_B | |
502 (mult:VSX_B | |
503 (match_operand:VSX_B 1 "vsx_register_operand" "") | |
504 (match_operand:VSX_B 2 "vsx_register_operand" "")) | |
505 (match_operand:VSX_B 3 "vsx_register_operand" "")))] | |
506 "VECTOR_UNIT_VSX_P (<MODE>mode)" | |
507 { | |
508 if (!TARGET_FUSED_MADD) | |
509 { | |
510 emit_insn (gen_vsx_fmadd<mode>4_2 (operands[0], operands[1], operands[2], | |
511 operands[3])); | |
512 DONE; | |
513 } | |
514 }) | |
515 | |
516 (define_insn "*vsx_fmadd<mode>4_1" | |
517 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") | 530 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") |
518 (plus:VSX_B | 531 (fma:VSX_B |
519 (mult:VSX_B | |
520 (match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") | 532 (match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") |
521 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")) | 533 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0") |
522 (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")))] | 534 (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")))] |
523 "VECTOR_UNIT_VSX_P (<MODE>mode) && TARGET_FUSED_MADD" | 535 "VECTOR_UNIT_VSX_P (<MODE>mode)" |
524 "@ | 536 "@ |
525 x<VSv>madda<VSs> %x0,%x1,%x2 | 537 x<VSv>madda<VSs> %x0,%x1,%x2 |
526 x<VSv>maddm<VSs> %x0,%x1,%x3 | 538 x<VSv>maddm<VSs> %x0,%x1,%x3 |
527 x<VSv>madda<VSs> %x0,%x1,%x2 | 539 x<VSv>madda<VSs> %x0,%x1,%x2 |
528 x<VSv>maddm<VSs> %x0,%x1,%x3" | 540 x<VSv>maddm<VSs> %x0,%x1,%x3" |
529 [(set_attr "type" "<VStype_mul>") | 541 [(set_attr "type" "<VStype_mul>") |
530 (set_attr "fp_type" "<VSfptype_mul>")]) | 542 (set_attr "fp_type" "<VSfptype_mul>")]) |
531 | 543 |
532 (define_insn "vsx_fmadd<mode>4_2" | 544 (define_insn "*vsx_fms<mode>4" |
533 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") | 545 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") |
534 (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") | 546 (fma:VSX_B |
535 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0") | |
536 (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")] | |
537 UNSPEC_VSX_MADD))] | |
538 "VECTOR_UNIT_VSX_P (<MODE>mode)" | |
539 "@ | |
540 x<VSv>madda<VSs> %x0,%x1,%x2 | |
541 x<VSv>maddm<VSs> %x0,%x1,%x3 | |
542 x<VSv>madda<VSs> %x0,%x1,%x2 | |
543 x<VSv>maddm<VSs> %x0,%x1,%x3" | |
544 [(set_attr "type" "<VStype_mul>") | |
545 (set_attr "fp_type" "<VSfptype_mul>")]) | |
546 | |
547 (define_expand "vsx_fmsub<mode>4" | |
548 [(set (match_operand:VSX_B 0 "vsx_register_operand" "") | |
549 (minus:VSX_B | |
550 (mult:VSX_B | |
551 (match_operand:VSX_B 1 "vsx_register_operand" "") | |
552 (match_operand:VSX_B 2 "vsx_register_operand" "")) | |
553 (match_operand:VSX_B 3 "vsx_register_operand" "")))] | |
554 "VECTOR_UNIT_VSX_P (<MODE>mode)" | |
555 { | |
556 if (!TARGET_FUSED_MADD) | |
557 { | |
558 emit_insn (gen_vsx_fmsub<mode>4_2 (operands[0], operands[1], operands[2], | |
559 operands[3])); | |
560 DONE; | |
561 } | |
562 }) | |
563 | |
564 (define_insn "*vsx_fmsub<mode>4_1" | |
565 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") | |
566 (minus:VSX_B | |
567 (mult:VSX_B | |
568 (match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") | 547 (match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") |
569 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")) | 548 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0") |
570 (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")))] | 549 (neg:VSX_B |
571 "VECTOR_UNIT_VSX_P (<MODE>mode) && TARGET_FUSED_MADD" | 550 (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa"))))] |
551 "VECTOR_UNIT_VSX_P (<MODE>mode)" | |
572 "@ | 552 "@ |
573 x<VSv>msuba<VSs> %x0,%x1,%x2 | 553 x<VSv>msuba<VSs> %x0,%x1,%x2 |
574 x<VSv>msubm<VSs> %x0,%x1,%x3 | 554 x<VSv>msubm<VSs> %x0,%x1,%x3 |
575 x<VSv>msuba<VSs> %x0,%x1,%x2 | 555 x<VSv>msuba<VSs> %x0,%x1,%x2 |
576 x<VSv>msubm<VSs> %x0,%x1,%x3" | 556 x<VSv>msubm<VSs> %x0,%x1,%x3" |
577 [(set_attr "type" "<VStype_mul>") | 557 [(set_attr "type" "<VStype_mul>") |
578 (set_attr "fp_type" "<VSfptype_mul>")]) | 558 (set_attr "fp_type" "<VSfptype_mul>")]) |
579 | 559 |
580 (define_insn "vsx_fmsub<mode>4_2" | 560 (define_insn "*vsx_nfma<mode>4" |
581 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") | |
582 (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") | |
583 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0") | |
584 (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")] | |
585 UNSPEC_VSX_MSUB))] | |
586 "VECTOR_UNIT_VSX_P (<MODE>mode)" | |
587 "@ | |
588 x<VSv>msuba<VSs> %x0,%x1,%x2 | |
589 x<VSv>msubm<VSs> %x0,%x1,%x3 | |
590 x<VSv>msuba<VSs> %x0,%x1,%x2 | |
591 x<VSv>msubm<VSs> %x0,%x1,%x3" | |
592 [(set_attr "type" "<VStype_mul>") | |
593 (set_attr "fp_type" "<VSfptype_mul>")]) | |
594 | |
595 (define_expand "vsx_fnmadd<mode>4" | |
596 [(match_operand:VSX_B 0 "vsx_register_operand" "") | |
597 (match_operand:VSX_B 1 "vsx_register_operand" "") | |
598 (match_operand:VSX_B 2 "vsx_register_operand" "") | |
599 (match_operand:VSX_B 3 "vsx_register_operand" "")] | |
600 "VECTOR_UNIT_VSX_P (<MODE>mode)" | |
601 { | |
602 if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)) | |
603 { | |
604 emit_insn (gen_vsx_fnmadd<mode>4_1 (operands[0], operands[1], | |
605 operands[2], operands[3])); | |
606 DONE; | |
607 } | |
608 else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)) | |
609 { | |
610 emit_insn (gen_vsx_fnmadd<mode>4_2 (operands[0], operands[1], | |
611 operands[2], operands[3])); | |
612 DONE; | |
613 } | |
614 else | |
615 { | |
616 emit_insn (gen_vsx_fnmadd<mode>4_3 (operands[0], operands[1], | |
617 operands[2], operands[3])); | |
618 DONE; | |
619 } | |
620 }) | |
621 | |
622 (define_insn "vsx_fnmadd<mode>4_1" | |
623 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") | 561 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") |
624 (neg:VSX_B | 562 (neg:VSX_B |
625 (plus:VSX_B | 563 (fma:VSX_B |
626 (mult:VSX_B | 564 (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSr>,wa,wa") |
627 (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSr>,wa,wa") | 565 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0") |
628 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")) | |
629 (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa"))))] | 566 (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa"))))] |
630 "VECTOR_UNIT_VSX_P (<MODE>mode) && TARGET_FUSED_MADD | 567 "VECTOR_UNIT_VSX_P (<MODE>mode)" |
631 && HONOR_SIGNED_ZEROS (DFmode)" | |
632 "@ | 568 "@ |
633 x<VSv>nmadda<VSs> %x0,%x1,%x2 | 569 x<VSv>nmadda<VSs> %x0,%x1,%x2 |
634 x<VSv>nmaddm<VSs> %x0,%x1,%x3 | 570 x<VSv>nmaddm<VSs> %x0,%x1,%x3 |
635 x<VSv>nmadda<VSs> %x0,%x1,%x2 | 571 x<VSv>nmadda<VSs> %x0,%x1,%x2 |
636 x<VSv>nmaddm<VSs> %x0,%x1,%x3" | 572 x<VSv>nmaddm<VSs> %x0,%x1,%x3" |
637 [(set_attr "type" "<VStype_mul>") | 573 [(set_attr "type" "<VStype_mul>") |
638 (set_attr "fp_type" "<VSfptype_mul>")]) | 574 (set_attr "fp_type" "<VSfptype_mul>")]) |
639 | 575 |
640 (define_insn "vsx_fnmadd<mode>4_2" | 576 (define_insn "*vsx_nfms<mode>4" |
641 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") | |
642 (minus:VSX_B | |
643 (mult:VSX_B | |
644 (neg:VSX_B | |
645 (match_operand:VSX_B 1 "gpc_reg_operand" "<VSr>,<VSr>,wa,wa")) | |
646 (match_operand:VSX_B 2 "gpc_reg_operand" "<VSr>,0,wa,0")) | |
647 (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")))] | |
648 "VECTOR_UNIT_VSX_P (<MODE>mode) && TARGET_FUSED_MADD | |
649 && !HONOR_SIGNED_ZEROS (DFmode)" | |
650 "@ | |
651 x<VSv>nmadda<VSs> %x0,%x1,%x2 | |
652 x<VSv>nmaddm<VSs> %x0,%x1,%x3 | |
653 x<VSv>nmadda<VSs> %x0,%x1,%x2 | |
654 x<VSv>nmaddm<VSs> %x0,%x1,%x3" | |
655 [(set_attr "type" "<VStype_mul>") | |
656 (set_attr "fp_type" "<VSfptype_mul>")]) | |
657 | |
658 (define_insn "vsx_fnmadd<mode>4_3" | |
659 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") | |
660 (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,<VSr>,wa,wa") | |
661 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0") | |
662 (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")] | |
663 UNSPEC_VSX_NMADD))] | |
664 "VECTOR_UNIT_VSX_P (<MODE>mode)" | |
665 "@ | |
666 x<VSv>nmadda<VSs> %x0,%x1,%x2 | |
667 x<VSv>nmaddm<VSs> %x0,%x1,%x3 | |
668 x<VSv>nmadda<VSs> %x0,%x1,%x2 | |
669 x<VSv>nmaddm<VSs> %x0,%x1,%x3" | |
670 [(set_attr "type" "<VStype_mul>") | |
671 (set_attr "fp_type" "<VSfptype_mul>")]) | |
672 | |
673 (define_expand "vsx_fnmsub<mode>4" | |
674 [(match_operand:VSX_B 0 "vsx_register_operand" "") | |
675 (match_operand:VSX_B 1 "vsx_register_operand" "") | |
676 (match_operand:VSX_B 2 "vsx_register_operand" "") | |
677 (match_operand:VSX_B 3 "vsx_register_operand" "")] | |
678 "VECTOR_UNIT_VSX_P (<MODE>mode)" | |
679 { | |
680 if (TARGET_FUSED_MADD && HONOR_SIGNED_ZEROS (DFmode)) | |
681 { | |
682 emit_insn (gen_vsx_fnmsub<mode>4_1 (operands[0], operands[1], | |
683 operands[2], operands[3])); | |
684 DONE; | |
685 } | |
686 else if (TARGET_FUSED_MADD && !HONOR_SIGNED_ZEROS (DFmode)) | |
687 { | |
688 emit_insn (gen_vsx_fnmsub<mode>4_2 (operands[0], operands[1], | |
689 operands[2], operands[3])); | |
690 DONE; | |
691 } | |
692 else | |
693 { | |
694 emit_insn (gen_vsx_fnmsub<mode>4_3 (operands[0], operands[1], | |
695 operands[2], operands[3])); | |
696 DONE; | |
697 } | |
698 }) | |
699 | |
700 (define_insn "vsx_fnmsub<mode>4_1" | |
701 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") | 577 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") |
702 (neg:VSX_B | 578 (neg:VSX_B |
703 (minus:VSX_B | 579 (fma:VSX_B |
704 (mult:VSX_B | |
705 (match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") | 580 (match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") |
706 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0")) | 581 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0") |
707 (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa"))))] | 582 (neg:VSX_B |
708 "VECTOR_UNIT_VSX_P (<MODE>mode) && TARGET_FUSED_MADD | 583 (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")))))] |
709 && HONOR_SIGNED_ZEROS (DFmode)" | |
710 "@ | |
711 x<VSv>nmsuba<VSs> %x0,%x1,%x2 | |
712 x<VSv>nmsubm<VSs> %x0,%x1,%x3 | |
713 x<VSv>nmsuba<VSs> %x0,%x1,%x2 | |
714 x<VSv>nmsubm<VSs> %x0,%x1,%x3" | |
715 [(set_attr "type" "<VStype_mul>") | |
716 (set_attr "fp_type" "<VSfptype_mul>")]) | |
717 | |
718 (define_insn "vsx_fnmsub<mode>4_2" | |
719 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") | |
720 (minus:VSX_B | |
721 (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa") | |
722 (mult:VSX_B | |
723 (match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") | |
724 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0"))))] | |
725 "VECTOR_UNIT_VSX_P (<MODE>mode) && TARGET_FUSED_MADD | |
726 && !HONOR_SIGNED_ZEROS (DFmode)" | |
727 "@ | |
728 x<VSv>nmsuba<VSs> %x0,%x1,%x2 | |
729 x<VSv>nmsubm<VSs> %x0,%x1,%x3 | |
730 x<VSv>nmsuba<VSs> %x0,%x1,%x2 | |
731 x<VSv>nmsubm<VSs> %x0,%x1,%x3" | |
732 [(set_attr "type" "<VStype_mul>") | |
733 (set_attr "fp_type" "<VSfptype_mul>")]) | |
734 | |
735 (define_insn "vsx_fnmsub<mode>4_3" | |
736 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,<VSr>,?wa,?wa") | |
737 (unspec:VSX_B [(match_operand:VSX_B 1 "vsx_register_operand" "%<VSr>,<VSr>,wa,wa") | |
738 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,0,wa,0") | |
739 (match_operand:VSX_B 3 "vsx_register_operand" "0,<VSr>,0,wa")] | |
740 UNSPEC_VSX_NMSUB))] | |
741 "VECTOR_UNIT_VSX_P (<MODE>mode)" | 584 "VECTOR_UNIT_VSX_P (<MODE>mode)" |
742 "@ | 585 "@ |
743 x<VSv>nmsuba<VSs> %x0,%x1,%x2 | 586 x<VSv>nmsuba<VSs> %x0,%x1,%x2 |
744 x<VSv>nmsubm<VSs> %x0,%x1,%x3 | 587 x<VSv>nmsubm<VSs> %x0,%x1,%x3 |
745 x<VSv>nmsuba<VSs> %x0,%x1,%x2 | 588 x<VSv>nmsuba<VSs> %x0,%x1,%x2 |
850 [(set_attr "type" "vecperm")]) | 693 [(set_attr "type" "vecperm")]) |
851 | 694 |
852 ;; Copy sign | 695 ;; Copy sign |
853 (define_insn "vsx_copysign<mode>3" | 696 (define_insn "vsx_copysign<mode>3" |
854 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") | 697 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") |
855 (if_then_else:VSX_B | 698 (unspec:VSX_B |
856 (ge:VSX_B (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa") | 699 [(match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa") |
857 (match_operand:VSX_B 3 "zero_constant" "j,j")) | 700 (match_operand:VSX_B 2 "vsx_register_operand" "<VSr>,wa")] |
858 (abs:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")) | 701 UNSPEC_COPYSIGN))] |
859 (neg:VSX_B (abs:VSX_B (match_dup 1)))))] | |
860 "VECTOR_UNIT_VSX_P (<MODE>mode)" | 702 "VECTOR_UNIT_VSX_P (<MODE>mode)" |
861 "x<VSv>cpsgn<VSs> %x0,%x2,%x1" | 703 "x<VSv>cpsgn<VSs> %x0,%x2,%x1" |
862 [(set_attr "type" "<VStype_simple>") | 704 [(set_attr "type" "<VStype_simple>") |
863 (set_attr "fp_type" "<VSfptype_simple>")]) | 705 (set_attr "fp_type" "<VSfptype_simple>")]) |
864 | 706 |
865 ;; For the conversions, limit the register class for the integer value to be | 707 ;; For the conversions, limit the register class for the integer value to be |
866 ;; the fprs because we don't want to add the altivec registers to movdi/movsi. | 708 ;; the fprs because we don't want to add the altivec registers to movdi/movsi. |
867 ;; For the unsigned tests, there isn't a generic double -> unsigned conversion | 709 ;; For the unsigned tests, there isn't a generic double -> unsigned conversion |
868 ;; in rs6000.md so don't test VECTOR_UNIT_VSX_P, just test against VSX. | 710 ;; in rs6000.md so don't test VECTOR_UNIT_VSX_P, just test against VSX. |
711 ;; Don't use vsx_register_operand here, use gpc_reg_operand to match rs6000.md. | |
869 (define_insn "vsx_float<VSi><mode>2" | 712 (define_insn "vsx_float<VSi><mode>2" |
870 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") | 713 [(set (match_operand:VSX_B 0 "gpc_reg_operand" "=<VSr>,?wa") |
871 (float:VSX_B (match_operand:<VSI> 1 "vsx_register_operand" "<VSr2>,<VSr3>")))] | 714 (float:VSX_B (match_operand:<VSI> 1 "gpc_reg_operand" "<VSr2>,<VSr3>")))] |
872 "VECTOR_UNIT_VSX_P (<MODE>mode)" | 715 "VECTOR_UNIT_VSX_P (<MODE>mode)" |
873 "x<VSv>cvsx<VSc><VSs> %x0,%x1" | 716 "x<VSv>cvsx<VSc><VSs> %x0,%x1" |
874 [(set_attr "type" "<VStype_simple>") | 717 [(set_attr "type" "<VStype_simple>") |
875 (set_attr "fp_type" "<VSfptype_simple>")]) | 718 (set_attr "fp_type" "<VSfptype_simple>")]) |
876 | 719 |
877 (define_insn "vsx_floatuns<VSi><mode>2" | 720 (define_insn "vsx_floatuns<VSi><mode>2" |
878 [(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa") | 721 [(set (match_operand:VSX_B 0 "gpc_reg_operand" "=<VSr>,?wa") |
879 (unsigned_float:VSX_B (match_operand:<VSI> 1 "vsx_register_operand" "<VSr2>,<VSr3>")))] | 722 (unsigned_float:VSX_B (match_operand:<VSI> 1 "gpc_reg_operand" "<VSr2>,<VSr3>")))] |
880 "VECTOR_UNIT_VSX_P (<MODE>mode)" | 723 "VECTOR_UNIT_VSX_P (<MODE>mode)" |
881 "x<VSv>cvux<VSc><VSs> %x0,%x1" | 724 "x<VSv>cvux<VSc><VSs> %x0,%x1" |
882 [(set_attr "type" "<VStype_simple>") | 725 [(set_attr "type" "<VStype_simple>") |
883 (set_attr "fp_type" "<VSfptype_simple>")]) | 726 (set_attr "fp_type" "<VSfptype_simple>")]) |
884 | 727 |
885 (define_insn "vsx_fix_trunc<mode><VSi>2" | 728 (define_insn "vsx_fix_trunc<mode><VSi>2" |
886 [(set (match_operand:<VSI> 0 "vsx_register_operand" "=<VSr2>,?<VSr3>") | 729 [(set (match_operand:<VSI> 0 "gpc_reg_operand" "=<VSr2>,?<VSr3>") |
887 (fix:<VSI> (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))] | 730 (fix:<VSI> (match_operand:VSX_B 1 "gpc_reg_operand" "<VSr>,wa")))] |
888 "VECTOR_UNIT_VSX_P (<MODE>mode)" | 731 "VECTOR_UNIT_VSX_P (<MODE>mode)" |
889 "x<VSv>cv<VSs>sx<VSc>s %x0,%x1" | 732 "x<VSv>cv<VSs>sx<VSc>s %x0,%x1" |
890 [(set_attr "type" "<VStype_simple>") | 733 [(set_attr "type" "<VStype_simple>") |
891 (set_attr "fp_type" "<VSfptype_simple>")]) | 734 (set_attr "fp_type" "<VSfptype_simple>")]) |
892 | 735 |
893 (define_insn "vsx_fixuns_trunc<mode><VSi>2" | 736 (define_insn "vsx_fixuns_trunc<mode><VSi>2" |
894 [(set (match_operand:<VSI> 0 "vsx_register_operand" "=<VSr2>,?<VSr3>") | 737 [(set (match_operand:<VSI> 0 "gpc_reg_operand" "=<VSr2>,?<VSr3>") |
895 (unsigned_fix:<VSI> (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))] | 738 (unsigned_fix:<VSI> (match_operand:VSX_B 1 "gpc_reg_operand" "<VSr>,wa")))] |
896 "VECTOR_UNIT_VSX_P (<MODE>mode)" | 739 "VECTOR_UNIT_VSX_P (<MODE>mode)" |
897 "x<VSv>cv<VSs>ux<VSc>s %x0,%x1" | 740 "x<VSv>cv<VSs>ux<VSc>s %x0,%x1" |
898 [(set_attr "type" "<VStype_simple>") | 741 [(set_attr "type" "<VStype_simple>") |
899 (set_attr "fp_type" "<VSfptype_simple>")]) | 742 (set_attr "fp_type" "<VSfptype_simple>")]) |
900 | 743 |
1052 (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")] | 895 (unspec:V2DI [(match_operand:V4SF 1 "vsx_register_operand" "wd,wa")] |
1053 UNSPEC_VSX_CVSPUXDS))] | 896 UNSPEC_VSX_CVSPUXDS))] |
1054 "VECTOR_UNIT_VSX_P (V2DFmode)" | 897 "VECTOR_UNIT_VSX_P (V2DFmode)" |
1055 "xvcvspuxds %x0,%x1" | 898 "xvcvspuxds %x0,%x1" |
1056 [(set_attr "type" "vecfloat")]) | 899 [(set_attr "type" "vecfloat")]) |
900 | |
901 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since | |
902 ;; since the xsrdpiz instruction does not truncate the value if the floating | |
903 ;; point value is < LONG_MIN or > LONG_MAX. | |
904 (define_insn "*vsx_float_fix_<mode>2" | |
905 [(set (match_operand:VSX_DF 0 "vsx_register_operand" "=<VSr>,?wa") | |
906 (float:VSX_DF | |
907 (fix:<VSI> | |
908 (match_operand:VSX_DF 1 "vsx_register_operand" "<VSr>,?wa"))))] | |
909 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT | |
910 && VECTOR_UNIT_VSX_P (<MODE>mode) && flag_unsafe_math_optimizations | |
911 && !flag_trapping_math && TARGET_FRIZ" | |
912 "x<VSv>r<VSs>iz %x0,%x1" | |
913 [(set_attr "type" "<VStype_simple>") | |
914 (set_attr "fp_type" "<VSfptype_simple>")]) | |
915 | |
1057 | 916 |
1058 ;; Logical and permute operations | 917 ;; Logical and permute operations |
1059 (define_insn "*vsx_and<mode>3" | 918 (define_insn "*vsx_and<mode>3" |
1060 [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") | 919 [(set (match_operand:VSX_L 0 "vsx_register_operand" "=<VSr>,?wa") |
1061 (and:VSX_L | 920 (and:VSX_L |