From 944e08418bf51bcbda9cace3cbf02c41d23be15c Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Tue, 3 Oct 2017 23:08:16 +0000 Subject: [PATCH] rs6000-builtin.def (BU_FLOAT128_2_HW): Define new helper macro for IEEE float128 hardware built-in functions. [gcc] 2017-10-03 Michael Meissner * config/rs6000/rs6000-builtin.def (BU_FLOAT128_2_HW): Define new helper macro for IEEE float128 hardware built-in functions. (SQRTF128_ODD): Add built-in functions with the round-to-odd semantics. (TRUNCF128_ODD): Likewise. (ADDF128_ODD): Likewise. (SUBF128_ODD): Likewise. (MULF128_ODD): Likewise. (DIVF128_ODD): Likewise. (FMAF128_ODD): Likewise. * config/rs6000/rs6000.md (UNSPEC_ROUND_TO_ODD): Rename to UNSPEC_TRUNC_ROUND_TO_ODD. (UNSPEC_TRUNC_ROUND_TO_ODD): Likewise. (UNSPEC_ADD_ROUND_TO_ODD): New unspec codes for the IEEE 128-bit floating point round to odd instructions. (UNSPEC_SUB_ROUND_TO_ODD): Likewise. (UNSPEC_MUL_ROUND_TO_ODD): Likewise. (UNSPEC_DIV_ROUND_TO_ODD): Likewise. (UNSPEC_FMA_ROUND_TO_ODD): Likewise. (UNSPEC_SQRT_ROUND_TO_ODD): Likewise. (truncsf2_hw): Change the truncate with round to odd expansion to use UNSPEC_TRUNC_ROUND_TO_ODD. (add3_odd): Add insns for IEEE 128-bit floating point round to odd hardware instructions. (sub3_odd): Likewise. (mul3_odd): Likewise. (div3_odd): Likewise. (sqrt2_odd): Likewise. (fma4_odd): Likewise. (fms4_odd): Likewise. (nfma4_odd): Likewise. (nfms4_odd): Likewise. (truncdf2_odd): Change the truncate with round to odd expansion to use UNSPEC_TRUNC_ROUND_TO_ODD. Add a generator function. * doc/extend.texi (PowerPC built-in functions): Update documentation for existing IEEE float128-bit built-in functions. Add built-in functions that generate the IEEE 128-bit floating point round to odd instructions. [gcc/testsuite] 2017-10-03 Michael Meissner * gcc.target/powerpc/float128-odd.c: New test. From-SVN: r253389 --- gcc/ChangeLog | 42 ++++++++ gcc/config/rs6000/rs6000-builtin.def | 26 ++++- gcc/config/rs6000/rs6000.md | 121 +++++++++++++++++++++++- gcc/doc/extend.texi | 41 +++++++- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gcc.target/powerpc/float128-odd.c | 75 +++++++++++++++ 6 files changed, 296 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/float128-odd.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9d43ae54b69..f7a448b3ecf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,45 @@ +2017-10-03 Michael Meissner + + * config/rs6000/rs6000-builtin.def (BU_FLOAT128_2_HW): Define new + helper macro for IEEE float128 hardware built-in functions. + (SQRTF128_ODD): Add built-in functions with the round-to-odd + semantics. + (TRUNCF128_ODD): Likewise. + (ADDF128_ODD): Likewise. + (SUBF128_ODD): Likewise. + (MULF128_ODD): Likewise. + (DIVF128_ODD): Likewise. + (FMAF128_ODD): Likewise. + * config/rs6000/rs6000.md (UNSPEC_ROUND_TO_ODD): Rename to + UNSPEC_TRUNC_ROUND_TO_ODD. + (UNSPEC_TRUNC_ROUND_TO_ODD): Likewise. + (UNSPEC_ADD_ROUND_TO_ODD): New unspec codes for the IEEE 128-bit + floating point round to odd instructions. + (UNSPEC_SUB_ROUND_TO_ODD): Likewise. + (UNSPEC_MUL_ROUND_TO_ODD): Likewise. + (UNSPEC_DIV_ROUND_TO_ODD): Likewise. + (UNSPEC_FMA_ROUND_TO_ODD): Likewise. + (UNSPEC_SQRT_ROUND_TO_ODD): Likewise. + (truncsf2_hw): Change the truncate with round to odd + expansion to use UNSPEC_TRUNC_ROUND_TO_ODD. + (add3_odd): Add insns for IEEE 128-bit floating point round + to odd hardware instructions. + (sub3_odd): Likewise. + (mul3_odd): Likewise. + (div3_odd): Likewise. + (sqrt2_odd): Likewise. + (fma4_odd): Likewise. + (fms4_odd): Likewise. + (nfma4_odd): Likewise. + (nfms4_odd): Likewise. + (truncdf2_odd): Change the truncate with round to odd + expansion to use UNSPEC_TRUNC_ROUND_TO_ODD. Add a generator + function. + * doc/extend.texi (PowerPC built-in functions): Update documentation + for existing IEEE float128-bit built-in functions. Add built-in + functions that generate the IEEE 128-bit floating point round to + odd instructions. + 2017-10-03 Segher Boessenkool PR rtl-optimization/77729 diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index 868b0cd14f6..ac9ddae3ef0 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -686,6 +686,14 @@ | RS6000_BTC_UNARY), \ CODE_FOR_ ## ICODE) /* ICODE */ +#define BU_FLOAT128_2_HW(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_FLOAT128_HW, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_BINARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + #define BU_FLOAT128_3_HW(ENUM, NAME, ATTR, ICODE) \ RS6000_BUILTIN_3 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ "__builtin_" NAME, /* NAME */ \ @@ -2365,11 +2373,19 @@ BU_P9_OVERLOAD_2 (CMPEQB, "byte_in_set") BU_FLOAT128_1 (FABSQ, "fabsq", CONST, abskf2) BU_FLOAT128_2 (COPYSIGNQ, "copysignq", CONST, copysignkf3) -/* 1 and 3 argument IEEE 128-bit floating point functions that require ISA 3.0 - hardware. These functions use the new 'f128' suffix. Eventually these - should be folded into the common built-in function handling. */ -BU_FLOAT128_1_HW (SQRTF128, "sqrtf128", CONST, sqrtkf2) -BU_FLOAT128_3_HW (FMAF128, "fmaf128", CONST, fmakf4_hw) +/* 1, 2, and 3 argument IEEE 128-bit floating point functions that require ISA + 3.0 hardware. These functions use the new 'f128' suffix. Eventually the + standard functions should be folded into the common built-in function + handling. */ +BU_FLOAT128_1_HW (SQRTF128, "sqrtf128", CONST, sqrtkf2) +BU_FLOAT128_1_HW (SQRTF128_ODD, "sqrtf128_round_to_odd", CONST, sqrtkf2_odd) +BU_FLOAT128_1_HW (TRUNCF128_ODD, "truncf128_round_to_odd", CONST, trunckfdf2_odd) +BU_FLOAT128_2_HW (ADDF128_ODD, "addf128_round_to_odd", CONST, addkf3_odd) +BU_FLOAT128_2_HW (SUBF128_ODD, "subf128_round_to_odd", CONST, subkf3_odd) +BU_FLOAT128_2_HW (MULF128_ODD, "mulf128_round_to_odd", CONST, mulkf3_odd) +BU_FLOAT128_2_HW (DIVF128_ODD, "divf128_round_to_odd", CONST, divkf3_odd) +BU_FLOAT128_3_HW (FMAF128, "fmaf128", CONST, fmakf4_hw) +BU_FLOAT128_3_HW (FMAF128_ODD, "fmaf128_round_to_odd", CONST, fmakf4_odd) /* 1 argument crypto functions. */ BU_CRYPTO_1 (VSBOX, "vsbox", CONST, crypto_vsbox) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 3181291a578..d8767dee05c 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -140,7 +140,13 @@ UNSPEC_STACK_CHECK UNSPEC_FUSION_P9 UNSPEC_FUSION_ADDIS - UNSPEC_ROUND_TO_ODD + UNSPEC_ADD_ROUND_TO_ODD + UNSPEC_SUB_ROUND_TO_ODD + UNSPEC_MUL_ROUND_TO_ODD + UNSPEC_DIV_ROUND_TO_ODD + UNSPEC_FMA_ROUND_TO_ODD + UNSPEC_SQRT_ROUND_TO_ODD + UNSPEC_TRUNC_ROUND_TO_ODD UNSPEC_SIGNBIT UNSPEC_SF_FROM_SI UNSPEC_SI_FROM_SF @@ -14505,7 +14511,8 @@ "#" "&& 1" [(set (match_dup 2) - (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD)) + (unspec:DF [(match_dup 1)] + UNSPEC_TRUNC_ROUND_TO_ODD)) (set (match_dup 0) (float_truncate:SF (match_dup 2)))] { @@ -14682,10 +14689,116 @@ (set_attr "size" "128")]) ;; IEEE 128-bit instructions with round to odd semantics -(define_insn "*truncdf2_odd" +(define_insn "add3_odd" + [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") + (unspec:IEEE128 + [(match_operand:IEEE128 1 "altivec_register_operand" "v") + (match_operand:IEEE128 2 "altivec_register_operand" "v")] + UNSPEC_ADD_ROUND_TO_ODD))] + "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" + "xsaddqpo %0,%1,%2" + [(set_attr "type" "vecfloat") + (set_attr "size" "128")]) + +(define_insn "sub3_odd" + [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") + (unspec:IEEE128 + [(match_operand:IEEE128 1 "altivec_register_operand" "v") + (match_operand:IEEE128 2 "altivec_register_operand" "v")] + UNSPEC_SUB_ROUND_TO_ODD))] + "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" + "xssubqpo %0,%1,%2" + [(set_attr "type" "vecfloat") + (set_attr "size" "128")]) + +(define_insn "mul3_odd" + [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") + (unspec:IEEE128 + [(match_operand:IEEE128 1 "altivec_register_operand" "v") + (match_operand:IEEE128 2 "altivec_register_operand" "v")] + UNSPEC_MUL_ROUND_TO_ODD))] + "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" + "xsmulqpo %0,%1,%2" + [(set_attr "type" "vecfloat") + (set_attr "size" "128")]) + +(define_insn "div3_odd" + [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") + (unspec:IEEE128 + [(match_operand:IEEE128 1 "altivec_register_operand" "v") + (match_operand:IEEE128 2 "altivec_register_operand" "v")] + UNSPEC_DIV_ROUND_TO_ODD))] + "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" + "xsdivqpo %0,%1,%2" + [(set_attr "type" "vecdiv") + (set_attr "size" "128")]) + +(define_insn "sqrt2_odd" + [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") + (unspec:IEEE128 + [(match_operand:IEEE128 1 "altivec_register_operand" "v")] + UNSPEC_SQRT_ROUND_TO_ODD))] + "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" + "xssqrtqpo %0,%1" + [(set_attr "type" "vecdiv") + (set_attr "size" "128")]) + +(define_insn "fma4_odd" + [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") + (unspec:IEEE128 + [(match_operand:IEEE128 1 "altivec_register_operand" "v") + (match_operand:IEEE128 2 "altivec_register_operand" "v") + (match_operand:IEEE128 3 "altivec_register_operand" "0")] + UNSPEC_FMA_ROUND_TO_ODD))] + "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" + "xsmaddqpo %0,%1,%2" + [(set_attr "type" "vecfloat") + (set_attr "size" "128")]) + +(define_insn "*fms4_odd" + [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") + (unspec:IEEE128 + [(match_operand:IEEE128 1 "altivec_register_operand" "%v") + (match_operand:IEEE128 2 "altivec_register_operand" "v") + (neg:IEEE128 + (match_operand:IEEE128 3 "altivec_register_operand" "0"))] + UNSPEC_FMA_ROUND_TO_ODD))] + "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" + "xsmsubqpo %0,%1,%2" + [(set_attr "type" "vecfloat") + (set_attr "size" "128")]) + +(define_insn "*nfma4_odd" + [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") + (neg:IEEE128 + (unspec:IEEE128 + [(match_operand:IEEE128 1 "altivec_register_operand" "%v") + (match_operand:IEEE128 2 "altivec_register_operand" "v") + (match_operand:IEEE128 3 "altivec_register_operand" "0")] + UNSPEC_FMA_ROUND_TO_ODD)))] + "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" + "xsnmaddqpo %0,%1,%2" + [(set_attr "type" "vecfloat") + (set_attr "size" "128")]) + +(define_insn "*nfms4_odd" + [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") + (neg:IEEE128 + (unspec:IEEE128 + [(match_operand:IEEE128 1 "altivec_register_operand" "%v") + (match_operand:IEEE128 2 "altivec_register_operand" "v") + (neg:IEEE128 + (match_operand:IEEE128 3 "altivec_register_operand" "0"))] + UNSPEC_FMA_ROUND_TO_ODD)))] + "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" + "xsnmsubqpo %0,%1,%2" + [(set_attr "type" "vecfloat") + (set_attr "size" "128")]) + +(define_insn "truncdf2_odd" [(set (match_operand:DF 0 "vsx_register_operand" "=v") (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")] - UNSPEC_ROUND_TO_ODD))] + UNSPEC_TRUNC_ROUND_TO_ODD))] "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" "xscvqpdpo %0,%1" [(set_attr "type" "vecfloat") diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 9064561b4fa..4156291b642 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -15348,14 +15348,47 @@ that use the ISA 3.0 instruction set. @table @code @item __float128 __builtin_sqrtf128 (__float128) -Similar to @code{__builtin_sqrtf}, except the return and input types -are @code{__float128}. +Perform a 128-bit IEEE floating point square root operation. @findex __builtin_sqrtf128 @item __float128 __builtin_fmaf128 (__float128, __float128, __float128) -Similar to @code{__builtin_fma}, except the return and input types are -@code{__float128}. +Perform a 128-bit IEEE floating point fused multiply and add operation. @findex __builtin_fmaf128 + +@item __float128 __builtin_addf128_round_to_odd (__float128, __float128) +Perform a 128-bit IEEE floating point add using round to odd as the +rounding mode. +@findex __builtin_addf128_round_to_odd + +@item __float128 __builtin_subf128_round_to_odd (__float128, __float128) +Perform a 128-bit IEEE floating point subtract using round to odd as +the rounding mode. +@findex __builtin_subf128_round_to_odd + +@item __float128 __builtin_mulf128_round_to_odd (__float128, __float128) +Perform a 128-bit IEEE floating point multiply using round to odd as +the rounding mode. +@findex __builtin_mulf128_round_to_odd + +@item __float128 __builtin_divf128_round_to_odd (__float128, __float128) +Perform a 128-bit IEEE floating point divide using round to odd as +the rounding mode. +@findex __builtin_divf128_round_to_odd + +@item __float128 __builtin_sqrtf128_round_to_odd (__float128) +Perform a 128-bit IEEE floating point square root using round to odd +as the rounding mode. +@findex __builtin_sqrtf128_round_to_odd + +@item __float128 __builtin_fmaf128 (__float128, __float128, __float128) +Perform a 128-bit IEEE floating point fused multiply and add operation +using round to odd as the rounding mode. +@findex __builtin_fmaf128_round_to_odd + +@item double __builtin_truncf128_round_to_odd (__float128) +Convert a 128-bit IEEE floating point value to @code{double} using +round to odd as the rounding mode. +@findex __builtin_truncf128_round_to_odd @end table The following built-in functions are available for the PowerPC family diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 49cd60eb059..7bd355603cc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-10-03 Michael Meissner + + * gcc.target/powerpc/float128-odd.c: New test. + 2017-10-03 Paolo Carlini PR c++/70343 diff --git a/gcc/testsuite/gcc.target/powerpc/float128-odd.c b/gcc/testsuite/gcc.target/powerpc/float128-odd.c new file mode 100644 index 00000000000..68c151059bc --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/float128-odd.c @@ -0,0 +1,75 @@ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-mpower9-vector -O2" } */ + +/* Test the generation of the round to odd instructions. */ +__float128 +f128_add(__float128 a, __float128 b) +{ + return __builtin_addf128_round_to_odd (a, b); +} + +__float128 +f128_sub (__float128 a, __float128 b) +{ + return __builtin_subf128_round_to_odd (a, b); +} + +__float128 +f128_mul (__float128 a, __float128 b) +{ + return __builtin_mulf128_round_to_odd (a, b); +} + +__float128 +f128_div (__float128 a, __float128 b) +{ + return __builtin_divf128_round_to_odd (a, b); +} + +__float128 +f128_sqrt (__float128 a) +{ + return __builtin_sqrtf128_round_to_odd (a); +} + +double +f128_trunc (__float128 a) +{ + return __builtin_truncf128_round_to_odd (a); +} + +__float128 +f128_fma (__float128 a, __float128 b, __float128 c) +{ + return __builtin_fmaf128_round_to_odd (a, b, c); +} + +__float128 +f128_fms (__float128 a, __float128 b, __float128 c) +{ + return __builtin_fmaf128_round_to_odd (a, b, -c); +} + +__float128 +f128_nfma (__float128 a, __float128 b, __float128 c) +{ + return - __builtin_fmaf128_round_to_odd (a, b, c); +} + +__float128 +f128_nfms (__float128 a, __float128 b, __float128 c) +{ + return - __builtin_fmaf128_round_to_odd (a, b, -c); +} + +/* { dg-final { scan-assembler {\mxsaddqpo\M} } } */ +/* { dg-final { scan-assembler {\mxssubqpo\M} } } */ +/* { dg-final { scan-assembler {\mxsmulqpo\M} } } */ +/* { dg-final { scan-assembler {\mxsdivqpo\M} } } */ +/* { dg-final { scan-assembler {\mxssqrtqpo\M} } } */ +/* { dg-final { scan-assembler {\mxscvqpdpo\M} } } */ +/* { dg-final { scan-assembler {\mxsmaddqpo\M} } } */ +/* { dg-final { scan-assembler {\mxsmsubqpo\M} } } */ +/* { dg-final { scan-assembler {\mxsnmaddqpo\M} } } */ +/* { dg-final { scan-assembler {\mxsnmsubqpo\M} } } */ -- 2.11.4.GIT