+2018-01-02 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000.md (floor<mode>2): Add support for IEEE
+ 128-bit round to integer instructions.
+ (ceil<mode>2): Likewise.
+ (btrunc<mode>2): Likewise.
+ (round<mode>2): Likewise.
+
2018-01-02 Aaron Sawdey <acsawdey@linux.vnet.ibm.com>
* config/rs6000/rs6000-string.c (expand_block_move): Allow the use of
(set_attr "type" "vecfloat")
(set_attr "size" "128")])
+;; IEEE 128-bit round to integer built-in functions
+(define_insn "floor<mode>2"
+ [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+ (unspec:IEEE128
+ [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
+ UNSPEC_FRIM))]
+ "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+ "xsrqpi 1,%0,%1,3"
+ [(set_attr "type" "vecfloat")
+ (set_attr "size" "128")])
+
+(define_insn "ceil<mode>2"
+ [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+ (unspec:IEEE128
+ [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
+ UNSPEC_FRIP))]
+ "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+ "xsrqpi 1,%0,%1,2"
+ [(set_attr "type" "vecfloat")
+ (set_attr "size" "128")])
+
+(define_insn "btrunc<mode>2"
+ [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+ (unspec:IEEE128
+ [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
+ UNSPEC_FRIZ))]
+ "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+ "xsrqpi 1,%0,%1,1"
+ [(set_attr "type" "vecfloat")
+ (set_attr "size" "128")])
+
+(define_insn "round<mode>2"
+ [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+ (unspec:IEEE128
+ [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
+ UNSPEC_FRIN))]
+ "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+ "xsrqpi 0,%0,%1,0"
+ [(set_attr "type" "vecfloat")
+ (set_attr "size" "128")])
+
;; IEEE 128-bit instructions with round to odd semantics
(define_insn "add<mode>3_odd"
[(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+2018-01-02 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/float128-hw2.c: Add tests for ceilf128,
+ floorf128, truncf128, and roundf128.
+ * gcc.target/powerpc/float128-hw5.c: New tests for _Float128
+ optimizations added in match.pd.
+ * gcc.target/powerpc/float128-hw6.c: Likewise.
+ * gcc.target/powerpc/float128-hw7.c: Likewise.
+ * gcc.target/powerpc/float128-hw8.c: Likewise.
+ * gcc.target/powerpc/float128-hw9.c: Likewise.
+ * gcc.target/powerpc/float128-hw10.c: Likewise.
+ * gcc.target/powerpc/float128-hw11.c: Likewise.
+
2018-01-02 Jakub Jelinek <jakub@redhat.com>
PR c++/83556
--- /dev/null
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2" } */
+
+extern _Float128 floorf128 (_Float128);
+extern _Float128 ceilf128 (_Float128);
+extern _Float128 roundf128 (_Float128);
+extern _Float128 truncf128 (_Float128);
+
+/* Check rounding optimizations that are done for double are also done for
+ _Float128. */
+
+_Float128
+floor_floor_x (_Float128 x)
+{
+ return floorf128 (floorf128 (x));
+}
+
+_Float128
+ceil_ceil_x (_Float128 x)
+{
+ return ceilf128 (ceilf128 (x));
+}
+
+_Float128
+trunc_trunc_x (_Float128 x)
+{
+ return truncf128 (truncf128 (x));
+}
+
+_Float128
+round_round_x (_Float128 x)
+{
+ return roundf128 (roundf128 (x));
+}
+
+/* { dg-final { scan-assembler-times {\mxsrqpi\M} 4 } } */
+/* { dg-final { scan-assembler-not {\mbl\M} } } */
--- /dev/null
+/* { dg-do run { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mpower9-vector -O2" } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
+#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1
+
+#include <math.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+extern _Float128 roundf128 (_Float128);
+extern _Float128 floorf128 (_Float128);
+extern _Float128 ceilf128 (_Float128);
+extern _Float128 truncf128 (_Float128);
+
+static const struct {
+ _Float128 value;
+ _Float128 exp_round;
+ _Float128 exp_floor;
+ _Float128 exp_ceil;
+ _Float128 exp_trunc;
+} a[] = {
+ { -2.0Q, -2.0Q, -2.0Q, -2.0Q, -2.0Q },
+ { -1.7Q, -2.0Q, -2.0Q, -1.0Q, -1.0Q },
+ { -1.5Q, -2.0Q, -2.0Q, -1.0Q, -1.0Q },
+ { -1.3Q, -1.0Q, -2.0Q, -1.0Q, -1.0Q },
+ { +0.0Q, +0.0Q, +0.0Q, +0.0Q, +0.0Q },
+ { +1.3Q, +1.0Q, +1.0Q, +2.0Q, +1.0Q },
+ { +1.5Q, +2.0Q, +1.0Q, +2.0Q, +1.0Q },
+ { +1.7Q, +2.0Q, +1.0Q, +2.0Q, +1.0Q },
+ { +2.0Q, +2.0Q, +2.0Q, +2.0Q, +2.0Q }
+};
+
+int
+main (void)
+{
+ size_t i;
+ _Float128 v;
+
+ for (i = 0; i < sizeof (a) / sizeof (a[0]); i++)
+ {
+ v = a[i].value;
+ if (roundf128 (v) != a[i].exp_round)
+ abort ();
+
+ if (floorf128 (v) != a[i].exp_floor)
+ abort ();
+
+ if (ceilf128 (v) != a[i].exp_ceil)
+ abort ();
+
+ if (truncf128 (v) != a[i].exp_trunc)
+ abort ();
+ }
+
+ return 0;
+}
extern _Float128 copysignf128 (_Float128, _Float128);
extern _Float128 sqrtf128 (_Float128);
extern _Float128 fmaf128 (_Float128, _Float128, _Float128);
+extern _Float128 ceilf128 (_Float128);
+extern _Float128 floorf128 (_Float128);
+extern _Float128 truncf128 (_Float128);
+extern _Float128 roundf128 (_Float128);
_Float128
do_copysign (_Float128 a, _Float128 b)
return -fmaf128 (a, b, -c);
}
+_Float128
+do_ceil (_Float128 a)
+{
+ return ceilf128 (a);
+}
+
+_Float128
+do_floor (_Float128 a)
+{
+ return floorf128 (a);
+}
+
+_Float128
+do_trunc (_Float128 a)
+{
+ return truncf128 (a);
+}
+
+_Float128
+do_round (_Float128 a)
+{
+ return roundf128 (a);
+}
+
/* { dg-final { scan-assembler {\mxscpsgnqp\M} } } */
/* { dg-final { scan-assembler {\mxssqrtqp\M} } } */
/* { dg-final { scan-assembler {\mxsmaddqp\M} } } */
/* { dg-final { scan-assembler {\mxsmsubqp\M} } } */
/* { dg-final { scan-assembler {\mxsnmaddqp\M} } } */
/* { dg-final { scan-assembler {\mxsnmsubqp\M} } } */
+/* { dg-final { scan-assembler {\mxsrqpi\M} } } */
/* { dg-final { scan-assembler-not {\mbl\M} } } */
--- /dev/null
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -ffast-math" } */
+
+extern _Float128 copysignf128 (_Float128, _Float128);
+
+/* Check copysign optimizations that are done for double are also done for
+ _Float128. */
+
+_Float128
+x_times_cs_one_negx (_Float128 x)
+{
+ return x * copysignf128 (1.0Q, -x); /* XSNABSQP */
+}
+
+_Float128
+x_times_cs_one_x (_Float128 x)
+{
+ return x * copysignf128 (1.0Q, x); /* XSABSQP */
+}
+
+_Float128
+cs_x_x (_Float128 x)
+{
+ return copysignf128 (x, x); /* no operation. */
+}
+
+/* { dg-final { scan-assembler-times {\mxsabsqp\M} 1 } } */
+/* { dg-final { scan-assembler-times {\mxsnabsqp\M} 1 } } */
+/* { dg-final { scan-assembler-not {\mxscpsgnqp\M} } } */
+/* { dg-final { scan-assembler-not {\mlxvx\M} } } */
+/* { dg-final { scan-assembler-not {\mlxv\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M} } } */
--- /dev/null
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2" } */
+
+extern _Float128 fabsf128 (_Float128);
+extern _Float128 copysignf128 (_Float128, _Float128);
+
+/* Check copysign optimizations that are done for double are also done for
+ _Float128. */
+
+_Float128
+cs_negx_y (_Float128 x, _Float128 y)
+{
+ return copysignf128 (-x, y); /* eliminate negation. */
+}
+
+_Float128
+cs_absx_y (_Float128 x, _Float128 y)
+{
+ return copysignf128 (fabsf128 (x), y); /* eliminate fabsf128. */
+}
+
+/* { dg-final { scan-assembler-times {\mxscpsgnqp\M} 2 } } */
+/* { dg-final { scan-assembler-not {\mxsnegqp\M} } } */
+/* { dg-final { scan-assembler-not {\mxsabsqp\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M} } } */
--- /dev/null
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2" } */
+
+extern _Float128 fabsf128 (_Float128);
+extern _Float128 copysignf128 (_Float128, _Float128);
+
+/* Check copysign optimizations that are done for double are also done for
+ _Float128. */
+
+_Float128
+cs_x_pos1 (_Float128 x)
+{
+ return copysignf128 (x, 1.0Q); /* XSABSQP. */
+}
+
+_Float128 cs_x_neg2 (_Float128 x)
+{
+ return copysignf128 (x, -2.0Q); /* XSNABSQP. */
+}
+
+/* { dg-final { scan-assembler-times {\mxsabsqp\M} 1 } } */
+/* { dg-final { scan-assembler-not {\mxsnabsqp\M} 1 } } */
+/* { dg-final { scan-assembler-not {\mxscpsgnqp\M} } } */
+/* { dg-final { scan-assembler-not {\mlxvx\M} } } */
+/* { dg-final { scan-assembler-not {\mlxv\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M} } } */
--- /dev/null
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2" } */
+
+extern _Float128 fminf128 (_Float128, _Float128);
+extern _Float128 fmaxf128 (_Float128, _Float128);
+
+/* Check min/max optimizations that are done for double are also done for
+ _Float128. */
+
+_Float128
+min_x_x (_Float128 x)
+{
+ return fminf128 (x, x);
+}
+
+_Float128
+max_x_x (_Float128 x)
+{
+ return fmaxf128 (x, x);
+}
+
+/* { dg-final { scan-assembler-not {\mxscmpuqp\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M} } } */
--- /dev/null
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -ffast-math" } */
+
+extern _Float128 sqrtf128 (_Float128);
+
+/* Check sqrt optimizations that are done for double are also done for
+ _Float128. */
+
+_Float128
+sqrt_x_times_sqrt_x (_Float128 x)
+{
+ return sqrtf128 (x) * sqrtf128 (x);
+}
+
+/* { dg-final { scan-assembler-not {\mxssqrtqp\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M} } } */