From ced8d882349226b8c566914826e8f59961240ad1 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Wed, 12 Sep 2018 10:58:42 +0000 Subject: [PATCH] S/390: Use proper rounding mode for DFP to BFD conversions According to IEEE 754 2008 4.3 'Rounding-direction attributes' the rounding mode of the target format needs to be used. By not setting the value so far we have always used the DFP rounding mode. gcc/ChangeLog: 2018-09-12 Andreas Krebbel * config/s390/s390.md (PFPO_RND_MODE_DFP, PFPO_RND_MODE_BFP): New constants. ("trunc2") ("trunc2") ("extend2") ("extend2"): Set proper rounding mode according to the target operand type. gcc/testsuite/ChangeLog: 2018-09-12 Andreas Krebbel * gcc.target/s390/dfp_to_bfp_rounding.c: New test. From-SVN: r264234 --- gcc/ChangeLog | 10 +++++++ gcc/config/s390/s390.md | 28 +++++++++++++++--- gcc/testsuite/ChangeLog | 4 +++ .../gcc.target/s390/dfp_to_bfp_rounding.c | 29 +++++++++++++++++++ 4 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/s390/dfp_to_bfp_rounding.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd0d8668bd5..77ef4bb08cc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2018-09-12 Andreas Krebbel + + * config/s390/s390.md (PFPO_RND_MODE_DFP, PFPO_RND_MODE_BFP): New + constants. + ("trunc2") + ("trunc2") + ("extend2") + ("extend2"): Set proper rounding mode + according to the target operand type. + 2018-09-12 Jakub Jelinek Andreas Krebbel diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index ddf8608b2a2..537ed35af18 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -404,6 +404,10 @@ ; Bitposition of operand types (PFPO_OP0_TYPE_SHIFT 16) (PFPO_OP1_TYPE_SHIFT 8) + ; Decide whether current DFP or BFD rounding mode should be used + ; for the conversion. + (PFPO_RND_MODE_DFP 0) + (PFPO_RND_MODE_BFP 1) ]) ; Immediate operands for tbegin and tbeginc @@ -5377,9 +5381,13 @@ { HOST_WIDE_INT flags; + /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the + rounding mode of the target format needs to be used. */ + flags = (PFPO_CONVERT | PFPO_OP_TYPE_ << PFPO_OP0_TYPE_SHIFT | - PFPO_OP_TYPE_ << PFPO_OP1_TYPE_SHIFT); + PFPO_OP_TYPE_ << PFPO_OP1_TYPE_SHIFT | + PFPO_RND_MODE_DFP); operands[2] = GEN_INT (flags); }) @@ -5399,9 +5407,13 @@ { HOST_WIDE_INT flags; + /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the + rounding mode of the target format needs to be used. */ + flags = (PFPO_CONVERT | PFPO_OP_TYPE_ << PFPO_OP0_TYPE_SHIFT | - PFPO_OP_TYPE_ << PFPO_OP1_TYPE_SHIFT); + PFPO_OP_TYPE_ << PFPO_OP1_TYPE_SHIFT | + PFPO_RND_MODE_BFP); operands[2] = GEN_INT (flags); }) @@ -5442,9 +5454,13 @@ { HOST_WIDE_INT flags; + /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the + rounding mode of the target format needs to be used. */ + flags = (PFPO_CONVERT | PFPO_OP_TYPE_ << PFPO_OP0_TYPE_SHIFT | - PFPO_OP_TYPE_ << PFPO_OP1_TYPE_SHIFT); + PFPO_OP_TYPE_ << PFPO_OP1_TYPE_SHIFT | + PFPO_RND_MODE_DFP); operands[2] = GEN_INT (flags); }) @@ -5464,9 +5480,13 @@ { HOST_WIDE_INT flags; + /* According to IEEE 754 2008 4.3 'Rounding-direction attributes' the + rounding mode of the target format needs to be used. */ + flags = (PFPO_CONVERT | PFPO_OP_TYPE_ << PFPO_OP0_TYPE_SHIFT | - PFPO_OP_TYPE_ << PFPO_OP1_TYPE_SHIFT); + PFPO_OP_TYPE_ << PFPO_OP1_TYPE_SHIFT | + PFPO_RND_MODE_BFP); operands[2] = GEN_INT (flags); }) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1d38a8efb70..a29d014e64b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-09-12 Andreas Krebbel + + * gcc.target/s390/dfp_to_bfp_rounding.c: New test. + 2018-09-12 Jakub Jelinek Andreas Krebbel diff --git a/gcc/testsuite/gcc.target/s390/dfp_to_bfp_rounding.c b/gcc/testsuite/gcc.target/s390/dfp_to_bfp_rounding.c new file mode 100644 index 00000000000..9a32abfdea6 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/dfp_to_bfp_rounding.c @@ -0,0 +1,29 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mzarch -march=z10" } */ + +/* According to IEEE 754 2008 4.3 Conversion operations between + different radixes must use the rounding mode of the target radix. + On S/390 this means passing the right value in GPR0 to PFPO + instruction. */ + +#include + +double __attribute__((noclone,noinline)) +convert (_Decimal64 in) +{ + return (double)in; +} + +int +main () +{ + fesetround (FE_UPWARD); + + if (convert (1e-325DD) != __DBL_DENORM_MIN__) + __builtin_abort (); + + fesetround (FE_DOWNWARD); + + if (convert (-1e-325DD) != -__DBL_DENORM_MIN__) + __builtin_abort (); +} -- 2.30.2