On Fri, 2013-08-16 at 23:25 +0200, Jakub Jelinek wrote: > On Fri, Aug 16, 2013 at 04:18:18PM -0500, Peter Bergner wrote: > > --- gcc/config/rs6000/dfp.md (revision 201779) > > +++ gcc/config/rs6000/dfp.md (working copy) > > @@ -132,11 +132,14 @@ (define_expand "negtd2" > > "") > > > > (define_insn "*negtd2_fpr" > > - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") > > - (neg:TD (match_operand:TD 1 "gpc_reg_operand" "d")))] > > + [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d") > > + (neg:TD (match_operand:TD 1 "gpc_reg_operand" "d,0")))] > > I'm surprised if it works in this order, I'd expect that alternative 0 > would match even for the same regno and that the second alternative wouldn't > be tried.
Ok, updated to switch the order of the alternatives. This works...just like the previous one. I created two versions of the TD test case to test both alternatives and to make sure we get fmrs on the one and no fmrs on the other. Peter gcc/ * builtins.def (BUILT_IN_FABSD32): New DFP ABS builtin. (BUILT_IN_FABSD64): Likewise. (BUILT_IN_FABSD128): Likewise. * builtins.c (expand_builtin): Add support for new DFP ABS builtins. (fold_builtin_1): Likewise. * config/rs6000/dfp.md (*negtd2_fpr): Handle non-overlapping destination and source operands. (*abstd2_fpr): Likewise. (*nabstd2_fpr): Likewise. gcc/testsuite/ * gcc.target/powerpc/dfp-dd-2.c: New test. * gcc.target/powerpc/dfp-td-2.c: Likewise. * gcc.target/powerpc/dfp-td-3.c: Likewise. Index: gcc/builtins.c =================================================================== --- gcc/builtins.c (revision 201779) +++ gcc/builtins.c (working copy) @@ -5865,6 +5865,9 @@ expand_builtin (tree exp, rtx target, rt switch (fcode) { CASE_FLT_FN (BUILT_IN_FABS): + case BUILT_IN_FABSD32: + case BUILT_IN_FABSD64: + case BUILT_IN_FABSD128: target = expand_builtin_fabs (exp, target, subtarget); if (target) return target; @@ -10314,6 +10317,9 @@ fold_builtin_1 (location_t loc, tree fnd return fold_builtin_strlen (loc, type, arg0); CASE_FLT_FN (BUILT_IN_FABS): + case BUILT_IN_FABSD32: + case BUILT_IN_FABSD64: + case BUILT_IN_FABSD128: return fold_builtin_fabs (loc, arg0, type); case BUILT_IN_ABS: Index: gcc/builtins.def =================================================================== --- gcc/builtins.def (revision 201779) +++ gcc/builtins.def (working copy) @@ -257,6 +257,9 @@ DEF_C99_BUILTIN (BUILT_IN_EXPM1L, DEF_LIB_BUILTIN (BUILT_IN_FABS, "fabs", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSF, "fabsf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSL, "fabsl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_FABSD32, "fabsd32", BT_FN_DFLOAT32_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_FABSD64, "fabsd64", BT_FN_DFLOAT64_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_FABSD128, "fabsd128", BT_FN_DFLOAT128_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST) DEF_C99_BUILTIN (BUILT_IN_FDIM, "fdim", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_C99_BUILTIN (BUILT_IN_FDIMF, "fdimf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_C99_BUILTIN (BUILT_IN_FDIML, "fdiml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) Index: gcc/config/rs6000/dfp.md =================================================================== --- gcc/config/rs6000/dfp.md (revision 201779) +++ gcc/config/rs6000/dfp.md (working copy) @@ -132,11 +132,14 @@ (define_expand "negtd2" "") (define_insn "*negtd2_fpr" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (neg:TD (match_operand:TD 1 "gpc_reg_operand" "d")))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d") + (neg:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))] "TARGET_HARD_FLOAT && TARGET_FPRS" - "fneg %0,%1" - [(set_attr "type" "fp")]) + "@ + fneg %0,%1 + fneg %0,%1\;fmr %L0,%L1" + [(set_attr "type" "fp") + (set_attr "length" "4,8")]) (define_expand "abstd2" [(set (match_operand:TD 0 "gpc_reg_operand" "") @@ -145,18 +148,24 @@ (define_expand "abstd2" "") (define_insn "*abstd2_fpr" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (abs:TD (match_operand:TD 1 "gpc_reg_operand" "d")))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d") + (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))] "TARGET_HARD_FLOAT && TARGET_FPRS" - "fabs %0,%1" - [(set_attr "type" "fp")]) + "@ + fabs %0,%1 + fabs %0,%1\;fmr %L0,%L1" + [(set_attr "type" "fp") + (set_attr "length" "4,8")]) (define_insn "*nabstd2_fpr" - [(set (match_operand:TD 0 "gpc_reg_operand" "=d") - (neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "d"))))] + [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d") + (neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d"))))] "TARGET_HARD_FLOAT && TARGET_FPRS" - "fnabs %0,%1" - [(set_attr "type" "fp")]) + "@ + fnabs %0,%1 + fnabs %0,%1\;fmr %L0,%L1" + [(set_attr "type" "fp") + (set_attr "length" "4,8")]) ;; Hardware support for decimal floating point operations. Index: gcc/testsuite/gcc.target/powerpc/dfp-dd-2.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/dfp-dd-2.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/dfp-dd-2.c (revision 0) @@ -0,0 +1,26 @@ +/* Test generation of DFP instructions for POWER6. */ +/* { dg-do compile { target { powerpc*-*-linux* && powerpc_fprs } } } */ +/* { dg-options "-std=gnu99 -O1 -mcpu=power6" } */ + +/* { dg-final { scan-assembler-times "fneg" 1 } } */ +/* { dg-final { scan-assembler-times "fabs" 1 } } */ +/* { dg-final { scan-assembler-times "fnabs" 1 } } */ +/* { dg-final { scan-assembler-times "fmr" 0 } } */ + +_Decimal64 +func1 (_Decimal64 a, _Decimal64 b) +{ + return -b; +} + +_Decimal64 +func2 (_Decimal64 a, _Decimal64 b) +{ + return __builtin_fabsd64 (b); +} + +_Decimal64 +func3 (_Decimal64 a, _Decimal64 b) +{ + return - __builtin_fabsd64 (b); +} Index: gcc/testsuite/gcc.target/powerpc/dfp-td-2.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/dfp-td-2.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/dfp-td-2.c (revision 0) @@ -0,0 +1,29 @@ +/* Test generation of DFP instructions for POWER6. */ +/* { dg-do compile { target { powerpc*-*-linux* && powerpc_fprs } } } */ +/* { dg-options "-std=gnu99 -O1 -mcpu=power6" } */ + +/* { dg-final { scan-assembler-times "fneg" 1 } } */ +/* { dg-final { scan-assembler-times "fabs" 1 } } */ +/* { dg-final { scan-assembler-times "fnabs" 1 } } */ +/* { dg-final { scan-assembler-times "fmr" 0 } } */ + +/* These tests verify we only generate fneg, fabs and fnabs + instructions and no fmr's since these are done in place. */ + +_Decimal128 +func1 (_Decimal128 a) +{ + return -a; +} + +_Decimal128 +func2 (_Decimal128 a) +{ + return __builtin_fabsd128 (a); +} + +_Decimal128 +func3 (_Decimal128 a) +{ + return - __builtin_fabsd128 (a); +} Index: gcc/testsuite/gcc.target/powerpc/dfp-td-3.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/dfp-td-3.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/dfp-td-3.c (revision 0) @@ -0,0 +1,29 @@ +/* Test generation of DFP instructions for POWER6. */ +/* { dg-do compile { target { powerpc*-*-linux* && powerpc_fprs } } } */ +/* { dg-options "-std=gnu99 -O1 -mcpu=power6" } */ + +/* { dg-final { scan-assembler-times "fneg" 1 } } */ +/* { dg-final { scan-assembler-times "fabs" 1 } } */ +/* { dg-final { scan-assembler-times "fnabs" 1 } } */ +/* { dg-final { scan-assembler-times "fmr" 3 } } */ + +/* These tests verify we generate fneg, fabs and fnabs and + associated fmr's since these are not done in place. */ + +_Decimal128 +func1 (_Decimal128 a, _Decimal128 b) +{ + return -b; +} + +_Decimal128 +func2 (_Decimal128 a, _Decimal128 b) +{ + return __builtin_fabsd128 (b); +} + +_Decimal128 +func3 (_Decimal128 a, _Decimal128 b) +{ + return - __builtin_fabsd128 (b); +}