GCC Maintainers: The following patch adds support for a couple of requested builtins that convert from float/double to int / long using the current rounding mode. I initially posted an early version of this patch which generated redundant instructions.
The patch has been tested on powerpc64le-unknown-linux-gnu (Power 8 LE). Please let me know if the following patch is acceptable. Thanks. Carl Love ------------------------------------------------------------------ gcc/ChangeLog: 2017-09-08 Carl Love <c...@us.ibm.com> * config/rs6000/rs6000-builtin.def (FCTID, FCTIW): Add BU_P7_MISC_1 macro expansion for builtins. * config/rs6000/rs6000.md (fctid, fctiw): Add define_insn for the fctid and fctiw instructions. gcc/testsuite/ChangeLog: 2017-09-08 Carl Love <c...@us.ibm.com> * gcc.target/powerpc/builtin-fctid-fctiw-runnable.c: New test file for the __builtin_fctid and __builtin_fctiw builtins. --- gcc/config/rs6000/rs6000-builtin.def | 2 + gcc/config/rs6000/rs6000.md | 16 +++ .../powerpc/builtin-fctid-fctiw-runnable.c | 140 +++++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 gcc/testsuite/gcc.target/powerpc/builtin-fctid-fctiw-runnable.c diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index 850164a..c7983e9 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -2231,6 +2231,8 @@ BU_DFP_MISC_2 (DSCRIQ, "dscriq", CONST, dfp_dscri_td) /* 1 argument BCD functions added in ISA 2.06. */ BU_P7_MISC_1 (CDTBCD, "cdtbcd", CONST, cdtbcd) BU_P7_MISC_1 (CBCDTD, "cbcdtd", CONST, cbcdtd) +BU_P7_MISC_1 (FCTID, "fctid", CONST, fctid) +BU_P7_MISC_1 (FCTIW, "fctiw", CONST, fctiw) /* 2 argument BCD functions added in ISA 2.06. */ BU_P7_MISC_2 (ADDG6S, "addg6s", CONST, addg6s) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 20873ac..3113fe7 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -115,6 +115,8 @@ UNSPEC_CMPB UNSPEC_FCTIW UNSPEC_FCTID + UNSPEC_FCTID_INST + UNSPEC_FCTIW_INST UNSPEC_LFIWAX UNSPEC_LFIWZX UNSPEC_FCTIWUZ @@ -14054,6 +14056,20 @@ [(set_attr "type" "integer") (set_attr "length" "4")]) +(define_insn "fctid" + [(set (match_operand:DI 0 "gpc_reg_operand" "=d") + (unspec:DI [(match_operand:DF 1 "gpc_reg_operand" "d")] + UNSPEC_FCTID_INST))] + "" + "fctid %0,%1") + +(define_insn "fctiw" + [(set (match_operand:SI 0 "gpc_reg_operand" "=d") + (unspec:SI [(match_operand:DF 1 "gpc_reg_operand" "d")] + UNSPEC_FCTIW_INST))] + "" + "fctiw %0,%1") + (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE UNSPEC_DIVEO UNSPEC_DIVEU diff --git a/gcc/testsuite/gcc.target/powerpc/builtin-fctid-fctiw-runnable.c b/gcc/testsuite/gcc.target/powerpc/builtin-fctid-fctiw-runnable.c new file mode 100644 index 0000000..e6cf46f --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/builtin-fctid-fctiw-runnable.c @@ -0,0 +1,140 @@ +/* { dg-do run { target { powerpc64*-*-* && { lp64 && p8vector_hw } } } } */ +/* { dg-require-effective-target powerpc_p8vector_ok } */ +/* { dg-options "-mcpu=power8" } */ + +#define DEBUG 1 + +#ifdef DEBUG +#include <stdio.h> +#endif + +void abort (void); + +long +test_bi_lrint_1 (float __A) +{ + return (__builtin_fctid (__A)); +} +long +test_bi_lrint_2 (double __A) +{ + return (__builtin_fctid (__A)); +} + +int +test_bi_rint_1 (float __A) +{ + return (__builtin_fctiw (__A)); +} + +int +test_bi_rint_2 (double __A) +{ + return (__builtin_fctiw (__A)); +} + + +int main( void) +{ + signed long lx, expected_l; + double dy; + + signed int x, expected_i; + float y; + + dy = 1.45; + expected_l = 1; + lx = __builtin_fctid (dy); + + if( lx != expected_l) +#ifdef DEBUG + printf("ERROR: __builtin_fctid(dy= %f) = %ld, expected %ld\n", + dy, lx, expected_l); +#else + abort(); +#endif + + dy = 3.51; + expected_l = 4; + lx = __builtin_fctid (dy); + + if( lx != expected_l) +#ifdef DEBUG + printf("ERROR: __builtin_fctid(dy= %f) = %ld, expected %ld\n", + dy, lx, expected_l); +#else + abort(); +#endif + + dy = 5.57; + expected_i = 6; + x = __builtin_fctiw (dy); + + if( x != expected_i) +#ifdef DEBUG + printf("ERROR: __builtin_fctiw(dy= %f) = %d, expected %d\n", + dy, x, expected_i); +#else + abort(); +#endif + + y = 11.47; + expected_i = 11; + x = __builtin_fctiw (y); + + if( x != expected_i) +#ifdef DEBUG + printf("ERROR: __builtin_fctiw(y = %f) = %d, expected %d\n", + y, x, expected_i); +#else + abort(); +#endif + + y = 17.77; + expected_l = 18; + lx = test_bi_lrint_1 (y); + + if( lx != expected_l) +#ifdef DEBUG + printf("ERROR: function call test_bi_lrint_1 (y = %f) = %ld, expected %ld\n", + y, lx, expected_l); +#else + abort(); +#endif + + dy = 7.1; + expected_l = 7; + lx = test_bi_lrint_2 (dy); + + if( lx != expected_l) +#ifdef DEBUG + printf("ERROR: function call test_bi_lrint_2 (dy = %f) = %ld, expected %ld\n", + dy, lx, expected_l); +#else + abort(); +#endif + + y = 0.001; + expected_i = 0; + x = test_bi_rint_1 (y); + + if( x != expected_i) +#ifdef DEBUG + printf("ERROR: function call test_bi_rint_1 (y = %f) = %d, expected %d\n", + y, x, expected_i); +#else + abort(); +#endif + + dy = 0.9999; + expected_i = 1; + x = test_bi_rint_2 (dy); + + if( x != expected_i) +#ifdef DEBUG + printf("ERROR: function call test_bi_rint_2 (dy = %f) = %d, expected %d\n", + dy, x, expected_i); +#else + abort(); +#endif +} -- 1.9.1