diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/expr.cc | 39 | ||||
-rw-r--r-- | gcc/optabs-libfuncs.cc | 4 |
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)) |