GCC maintainers: The following patch has been updated to address Segher's comments. The patch. The new BU_FP_MISC_1 macro has been changed so gcc will gracefully exit when the command line option -msoft-float is used.
I have tested the patch on powerpc64le-unknown-linux-gnu (Power 8 LE). I also manually ran make -k check with --target_board=unix`{-m64,-m32}` against the test case to make sure it worked fine for both 32-bit and 64-bit. Please let me know if the following patch is acceptable. Thanks. Carl Love ------------------------------------------------------------------------- gcc/ChangeLog: 2017-09-21 Carl Love <c...@us.ibm.com> * config/rs6000/rs6000-builtin.def (BU_FP_1MISC_1): Add define macro. (FCTID, FCTIW): Add BU_FP_MISC_1 macro expansion for builtins. * config/rs6000/rs6000.md (lrintsfsi2): Add define_insn for the fctiw instruction. gcc/testsuite/ChangeLog: 2017-09-21 Carl Love <c...@us.ibm.com> * gcc.target/powerpc/builtin-fctid-fctiw-runnable.c: New test file for the __builtin_fctid and __builtin_fctiw. --- gcc/config/rs6000/rs6000-builtin.def | 14 +++ gcc/config/rs6000/rs6000.md | 8 ++ .../powerpc/builtin-fctid-fctiw-runnable.c | 137 +++++++++++++++++++++ 3 files changed, 159 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..90c10af 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -608,6 +608,16 @@ CODE_FOR_ ## ICODE) /* ICODE */ +/* Miscellaneous builtins for instructions added prior to ISA 2.04. These + operate on floating point registers. */ +#define BU_FP_MISC_1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_HARD_FLOAT, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ + | RS6000_BTC_UNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + /* Miscellaneous builtins for instructions added in ISA 2.06. These instructions don't require either the DFP or VSX options, just the basic ISA 2.06 (popcntd) enablement since they operate on general purpose @@ -1846,6 +1856,10 @@ BU_VSX_OVERLOAD_X (XL, "xl") BU_VSX_OVERLOAD_X (XL_BE, "xl_be") BU_VSX_OVERLOAD_X (XST, "xst") +/* 1 argument builtins pre ISA 2.04. */ +BU_FP_MISC_1 (FCTID, "fctid", CONST, lrintdfdi2) +BU_FP_MISC_1 (FCTIW, "fctiw", CONST, lrintsfsi2) + /* 2 argument CMPB instructions added in ISA 2.05. */ BU_P6_2 (CMPB_32, "cmpb_32", CONST, cmpbsi3) BU_P6_64BIT_2 (CMPB, "cmpb", CONST, cmpbdi3) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 20873ac..ad39dc9 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -5899,6 +5899,14 @@ [(set_attr "type" "fpload") (set_attr "length" "16")]) +(define_insn "lrintsfsi2" + [(set (match_operand:SI 0 "gpc_reg_operand" "=d") + (unspec:SI [(match_operand:DF 1 "gpc_reg_operand" "d")] + UNSPEC_FCTIW))] + "TARGET_SF_FPR && TARGET_FPRND" + "fctiw %0,%1" + [(set_attr "type" "fp")]) + ;; No VSX equivalent to fctid (define_insn "lrint<mode>di2" [(set (match_operand:DI 0 "gpc_reg_operand" "=d") 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..b99fae3 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/builtin-fctid-fctiw-runnable.c @@ -0,0 +1,137 @@ +/* { dg-do run { target { powerpc*-*-* && { lp64 && p8vector_hw } } } } */ +/* { dg-options "-mcpu=power8" } */ + +#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