aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meissner <meissner@linux.vnet.ibm.com>2010-11-03 20:35:34 +0000
committerMichael Meissner <meissner@gcc.gnu.org>2010-11-03 20:35:34 +0000
commit92d54f6df5e9455ff4c9425171ff3a0a67e07bd2 (patch)
treec8d3b13293610de5fcf133084a4d76dd1f025717
parent0787e2e7a766f7a358abdc88e9e6d339ec2ed30d (diff)
downloadgcc-92d54f6df5e9455ff4c9425171ff3a0a67e07bd2.zip
gcc-92d54f6df5e9455ff4c9425171ff3a0a67e07bd2.tar.gz
gcc-92d54f6df5e9455ff4c9425171ff3a0a67e07bd2.tar.bz2
Add SF min/max under VSX, using the normal double operations
From-SVN: r166273
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/rs6000/rs6000.c4
-rw-r--r--gcc/config/rs6000/vsx.md22
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vsx-sfminmax.c18
5 files changed, 55 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d9e67dc..5c6387e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2010-11-03 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_emit_minmax): Add support to use
+ xsmindp/xsmaxdp on VSX for single precision min/max.
+ * config/rs6000/vsx.md (vsx_smaxsf3): Ditto.
+ (vsx_sminsf3): Ditto.
+
2010-11-03 Eric Botcazou <ebotcazou@adacore.com>
* combine.c (try_combine): Fix formatting issues, improve comments and
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index d7d94ef..7ec6699 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -17205,7 +17205,9 @@ rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
rtx target;
/* VSX/altivec have direct min/max insns. */
- if ((code == SMAX || code == SMIN) && VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode))
+ if ((code == SMAX || code == SMIN)
+ && (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
+ || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
{
emit_insn (gen_rtx_SET (VOIDmode,
dest,
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index a861cc0..4e68987 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -437,6 +437,28 @@
[(set_attr "type" "<VStype_simple>")
(set_attr "fp_type" "<VSfptype_simple>")])
+;; Special VSX version of smin/smax for single precision floating point. Since
+;; both numbers are rounded to single precision, we can just use the DP version
+;; of the instruction.
+
+(define_insn "*vsx_smaxsf3"
+ [(set (match_operand:SF 0 "vsx_register_operand" "=f")
+ (smax:SF (match_operand:SF 1 "vsx_register_operand" "f")
+ (match_operand:SF 2 "vsx_register_operand" "f")))]
+ "VECTOR_UNIT_VSX_P (DFmode)"
+ "xsmaxdp %x0,%x1,%x2"
+ [(set_attr "type" "fp")
+ (set_attr "fp_type" "fp_addsub_d")])
+
+(define_insn "*vsx_sminsf3"
+ [(set (match_operand:SF 0 "vsx_register_operand" "=f")
+ (smin:SF (match_operand:SF 1 "vsx_register_operand" "f")
+ (match_operand:SF 2 "vsx_register_operand" "f")))]
+ "VECTOR_UNIT_VSX_P (DFmode)"
+ "xsmindp %x0,%x1,%x2"
+ [(set_attr "type" "fp")
+ (set_attr "fp_type" "fp_addsub_d")])
+
(define_insn "*vsx_sqrt<mode>2"
[(set (match_operand:VSX_B 0 "vsx_register_operand" "=<VSr>,?wa")
(sqrt:VSX_B (match_operand:VSX_B 1 "vsx_register_operand" "<VSr>,wa")))]
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index a2e1330..206798d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-11-03 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/vsx-sfminmax.c: New test for using double
+ precision min/max for single precision on VSX.
+
2010-11-03 Jason Merrill <jason@redhat.com>
PR c++/46289
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-sfminmax.c b/gcc/testsuite/gcc.target/powerpc/vsx-sfminmax.c
new file mode 100644
index 0000000..d05ee19
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vsx-sfminmax.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-O2 -mcpu=power7 -ffast-math" } */
+/* { dg-final { scan-assembler "xsmaxdp" } } */
+/* { dg-final { scan-assembler "xsmindp" } } */
+
+float
+do_fmin (float a, float b)
+{
+ return __builtin_fminf (a, b);
+}
+
+float
+do_fmax (float a, float b)
+{
+ return __builtin_fmaxf (a, b);
+}