aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/expr.cc39
-rw-r--r--gcc/optabs-libfuncs.cc4
2 files changed, 33 insertions, 10 deletions
diff --git a/gcc/expr.cc b/gcc/expr.cc
index ffbac51..2089c2b 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -338,6 +338,29 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp)
enum rtx_code equiv_code = (unsignedp < 0 ? UNKNOWN
: (unsignedp ? ZERO_EXTEND : SIGN_EXTEND));
+ auto acceptable_same_precision_modes
+ = [] (scalar_mode from_mode, scalar_mode to_mode) -> bool
+ {
+ if (DECIMAL_FLOAT_MODE_P (from_mode) != DECIMAL_FLOAT_MODE_P (to_mode))
+ return true;
+
+ /* arm_bfloat_half_format <-> ieee_half_format */
+ if ((REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
+ && REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
+ || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
+ && REAL_MODE_FORMAT (from_mode) == &ieee_half_format))
+ return true;
+
+ /* ibm_extended_format <-> ieee_quad_format */
+ if ((REAL_MODE_FORMAT (from_mode) == &ibm_extended_format
+ && REAL_MODE_FORMAT (to_mode) == &ieee_quad_format)
+ || (REAL_MODE_FORMAT (from_mode) == &ieee_quad_format
+ && REAL_MODE_FORMAT (to_mode) == &ibm_extended_format))
+ return true;
+
+ return false;
+ };
+
if (to_real)
{
rtx value;
@@ -346,18 +369,16 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp)
gcc_assert ((GET_MODE_PRECISION (from_mode)
!= GET_MODE_PRECISION (to_mode))
- || (DECIMAL_FLOAT_MODE_P (from_mode)
- != DECIMAL_FLOAT_MODE_P (to_mode))
- || (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
- && REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
- || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
- && REAL_MODE_FORMAT (from_mode) == &ieee_half_format));
+ || acceptable_same_precision_modes (from_mode, to_mode));
if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode))
{
- if (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
- && REAL_MODE_FORMAT (from_mode) == &ieee_half_format)
- /* libgcc implements just __trunchfbf2, not __extendhfbf2. */
+ if ((REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
+ && REAL_MODE_FORMAT (from_mode) == &ieee_half_format)
+ || (REAL_MODE_FORMAT (to_mode) == &ieee_quad_format
+ && REAL_MODE_FORMAT (from_mode) == &ibm_extended_format))
+ /* libgcc implements just __trunchfbf2, not __extendhfbf2;
+ and __trunctfkf2, not __extendtfkf2. */
tab = trunc_optab;
else
/* Conversion between decimal float and binary float, same
diff --git a/gcc/optabs-libfuncs.cc b/gcc/optabs-libfuncs.cc
index 2672991..ab97eac 100644
--- a/gcc/optabs-libfuncs.cc
+++ b/gcc/optabs-libfuncs.cc
@@ -591,7 +591,9 @@ gen_trunc_conv_libfunc (convert_optab tab,
if (GET_MODE_PRECISION (float_fmode) <= GET_MODE_PRECISION (float_tmode)
&& (REAL_MODE_FORMAT (float_tmode) != &arm_bfloat_half_format
- || REAL_MODE_FORMAT (float_fmode) != &ieee_half_format))
+ || REAL_MODE_FORMAT (float_fmode) != &ieee_half_format)
+ && (REAL_MODE_FORMAT (float_tmode) != &ieee_quad_format
+ || REAL_MODE_FORMAT (float_fmode) != &ibm_extended_format))
return;
if (GET_MODE_CLASS (float_tmode) == GET_MODE_CLASS (float_fmode))