diff options
author | Michael Meissner <meissner@linux.ibm.com> | 2021-06-17 22:05:16 -0400 |
---|---|---|
committer | Michael Meissner <meissner@linux.ibm.com> | 2021-06-17 22:05:16 -0400 |
commit | 7d08043da935095543172f91f691917bd6379c53 (patch) | |
tree | c7f3bebe4a23809c4a90d8b208ff7ae04b44f037 /gcc | |
parent | 688359a27d835bbdab554fdf5eb207f1bd678371 (diff) | |
download | gcc-7d08043da935095543172f91f691917bd6379c53.zip gcc-7d08043da935095543172f91f691917bd6379c53.tar.gz gcc-7d08043da935095543172f91f691917bd6379c53.tar.bz2 |
Add IEEE 128-bit min/max support on PowerPC.
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.
This patch does not try to re-use the code used for SF/DF min/max
support. It defines a separate insn for the IEEE 128-bit support. It
uses the code iterator <minmax> to simplify adding both operations.
GCC will not convert ternary operations into using min/max instructions
provided in this patch unless the user uses -Ofast. The next patch that adds
conditional move instructions will enable the ternary conversion in many cases.
gcc/
2021-06-17 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/xsmincqp instructions.
* config/rs6000/rs6000.md (s<minmax><mode>3, IEEE128 iterator):
New insns.
gcc/testsuite/
2021-06-17 Michael Meissner <meissner@linux.ibm.com>
* gcc.target/powerpc/float128-minmax-2.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 3 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/float128-minmax-2.c | 15 |
3 files changed, 28 insertions, 1 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 38f9281..2c249e1 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -16103,7 +16103,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)) + || (TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)))) { emit_insn (gen_rtx_SET (dest, gen_rtx_fmt_ee (code, mode, op0, op1))); return; diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 510dbff..abd825f 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -5214,6 +5214,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 && TARGET_FLOAT128_HW" + "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 0000000..c71ba08 --- /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} } } */ |