+2018-09-12 Andreas Krebbel <krebbel@linux.ibm.com>
+
+ * config/s390/s390.md (PFPO_RND_MODE_DFP, PFPO_RND_MODE_BFP): New
+ constants.
+ ("trunc<BFP:mode><DFP_ALL:mode>2")
+ ("trunc<DFP_ALL:mode><BFP:mode>2")
+ ("extend<BFP:mode><DFP_ALL:mode>2")
+ ("extend<DFP_ALL:mode><BFP:mode>2"): Set proper rounding mode
+ according to the target operand type.
+
2018-09-12 Jakub Jelinek <jakub@redhat.com>
Andreas Krebbel <krebbel@linux.ibm.com>
; 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
{
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_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
- PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
+ PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT |
+ PFPO_RND_MODE_DFP);
operands[2] = GEN_INT (flags);
})
{
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_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
- PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
+ PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT |
+ PFPO_RND_MODE_BFP);
operands[2] = GEN_INT (flags);
})
{
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_<DFP_ALL:MODE> << PFPO_OP0_TYPE_SHIFT |
- PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT);
+ PFPO_OP_TYPE_<BFP:MODE> << PFPO_OP1_TYPE_SHIFT |
+ PFPO_RND_MODE_DFP);
operands[2] = GEN_INT (flags);
})
{
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_<BFP:MODE> << PFPO_OP0_TYPE_SHIFT |
- PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT);
+ PFPO_OP_TYPE_<DFP_ALL:MODE> << PFPO_OP1_TYPE_SHIFT |
+ PFPO_RND_MODE_BFP);
operands[2] = GEN_INT (flags);
})
--- /dev/null
+/* { 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 <fenv.h>
+
+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 ();
+}