[gcc(refs/users/meissner/heads/work020)] Power10: Add IEEE 128-bit xsmaxcqp and xsmincqp support.
Michael Meissner
meissner@gcc.gnu.org
Tue Oct 13 13:46:18 GMT 2020
https://gcc.gnu.org/g:c24ac3b9028721af4aa6aca54299fa0155f881b7
commit c24ac3b9028721af4aa6aca54299fa0155f881b7
Author: Michael Meissner <meissner@linux.ibm.com>
Date: Tue Oct 13 09:45:46 2020 -0400
Power10: Add IEEE 128-bit xsmaxcqp and xsmincqp support.
This patch adds the support for the IEEE 128-bit floating point C minimum and
maximum instructions. The next patch will add the support for using the
compare and set mask instruction to implement conditional moves.
Rather than trying to overload the current SF/DF min/max support, it was
simpler to just provide the new instructions as a separate insn.
gcc/
2020-10-13 Michael Meissner <meissner@linux.ibm.com>
* config/rs6000/rs6000.c (rs6000_emit_minmax): Add support for ISA
3.1 IEEE 128-bit floating point xsmaxcqp and xsmincqp instructions.
* config/rs6000/rs60000.h (FLOAT128_MIN_MAX_FPMASK_P): New macro.
* config/rs6000/rs6000.md (s<minmax><mode>3): Add support for the
ISA 3.1 IEEE 128-bit minimum and maximum instructions.
gcc/testsuite/
2020-10-13 Michael Meissner <meissner@linux.ibm.com>
* gcc.target/powerpc/float128-minmax-2.c: New test.
Diff:
---
gcc/config/rs6000/rs6000.c | 3 ++-
gcc/config/rs6000/rs6000.h | 5 +++++
gcc/config/rs6000/rs6000.md | 11 +++++++++++
gcc/testsuite/gcc.target/powerpc/float128-minmax-2.c | 15 +++++++++++++++
4 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index b58eeae2b98..7427d859be9 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -15550,7 +15550,8 @@ rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
/* VSX/altivec have direct min/max insns. */
if ((code == SMAX || code == SMIN)
&& (VECTOR_UNIT_ALTIVEC_OR_VSX_P (mode)
- || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))))
+ || (mode == SFmode && VECTOR_UNIT_VSX_P (DFmode))
+ || FLOAT128_MIN_MAX_FPMASK_P (mode)))
{
emit_insn (gen_rtx_SET (dest, gen_rtx_fmt_ee (code, mode, op0, op1)));
return;
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index bbd8060e143..0f30b77ca5c 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -345,6 +345,11 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
|| ((MODE) == TDmode) \
|| (!TARGET_FLOAT128_TYPE && FLOAT128_IEEE_P (MODE)))
+/* Macro whether the float128 minimum, maximum, and set compare mask
+ instructions are enabled. */
+#define FLOAT128_MIN_MAX_FPMASK_P(MODE) \
+ (TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (MODE))
+
/* Return true for floating point that does not use a vector register. */
#define SCALAR_FLOAT_MODE_NOT_VECTOR_P(MODE) \
(SCALAR_FLOAT_MODE_P (MODE) && !FLOAT128_VECTOR_P (MODE))
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 779bfd11237..b3d809a8a5a 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -5163,6 +5163,17 @@
}
[(set_attr "type" "fp")])
+;; Min/max for ISA 3.1 IEEE 128-bit floating point
+(define_insn "s<minmax><mode>3"
+ [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+ (fp_minmax:IEEE128
+ (match_operand:IEEE128 1 "altivec_register_operand" "v")
+ (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
+ "TARGET_POWER10"
+ "xs<minmax>cqp %0,%1,%2"
+ [(set_attr "type" "vecfloat")
+ (set_attr "size" "128")])
+
;; The conditional move instructions allow us to perform max and min operations
;; even when we don't have the appropriate max/min instruction using the FSEL
;; instruction.
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-minmax-2.c b/gcc/testsuite/gcc.target/powerpc/float128-minmax-2.c
new file mode 100644
index 00000000000..c71ba08c9f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-minmax-2.c
@@ -0,0 +1,15 @@
+/* { dg-require-effective-target ppc_float128_hw } */
+/* { dg-require-effective-target power10_ok } */
+/* { dg-options "-mdejagnu-cpu=power10 -O2 -ffast-math" } */
+
+#ifndef TYPE
+#define TYPE _Float128
+#endif
+
+/* Test that the fminf128/fmaxf128 functions generate if/then/else and not a
+ call. */
+TYPE f128_min (TYPE a, TYPE b) { return __builtin_fminf128 (a, b); }
+TYPE f128_max (TYPE a, TYPE b) { return __builtin_fmaxf128 (a, b); }
+
+/* { dg-final { scan-assembler {\mxsmaxcqp\M} } } */
+/* { dg-final { scan-assembler {\mxsmincqp\M} } } */
More information about the Gcc-cvs
mailing list