aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/optabs.cc')
-rw-r--r--gcc/optabs.cc48
1 files changed, 46 insertions, 2 deletions
diff --git a/gcc/optabs.cc b/gcc/optabs.cc
index 4c641ca..c725f35 100644
--- a/gcc/optabs.cc
+++ b/gcc/optabs.cc
@@ -5674,7 +5674,21 @@ expand_fix (rtx to, rtx from, int unsignedp)
rtx_insn *last = get_last_insn ();
rtx from1 = from;
if (fmode != GET_MODE (from))
- from1 = convert_to_mode (fmode, from, 0);
+ {
+ if (REAL_MODE_FORMAT (GET_MODE (from))
+ == &arm_bfloat_half_format
+ && REAL_MODE_FORMAT (fmode) == &ieee_single_format)
+ /* The BF -> SF conversions can be just a shift, doesn't
+ need to handle sNANs. */
+ {
+ int save_flag_finite_math_only = flag_finite_math_only;
+ flag_finite_math_only = true;
+ from1 = convert_to_mode (fmode, from, 0);
+ flag_finite_math_only = save_flag_finite_math_only;
+ }
+ else
+ from1 = convert_to_mode (fmode, from, 0);
+ }
if (must_trunc)
{
@@ -5746,7 +5760,21 @@ expand_fix (rtx to, rtx from, int unsignedp)
lab2 = gen_label_rtx ();
if (fmode != GET_MODE (from))
- from = convert_to_mode (fmode, from, 0);
+ {
+ if (REAL_MODE_FORMAT (GET_MODE (from))
+ == &arm_bfloat_half_format
+ && REAL_MODE_FORMAT (fmode) == &ieee_single_format)
+ /* The BF -> SF conversions can be just a shift, doesn't
+ need to handle sNANs. */
+ {
+ int save_flag_finite_math_only = flag_finite_math_only;
+ flag_finite_math_only = true;
+ from = convert_to_mode (fmode, from, 0);
+ flag_finite_math_only = save_flag_finite_math_only;
+ }
+ else
+ from = convert_to_mode (fmode, from, 0);
+ }
/* See if we need to do the subtraction. */
do_pending_stack_adjust ();
@@ -5790,6 +5818,22 @@ expand_fix (rtx to, rtx from, int unsignedp)
}
}
+#ifdef HAVE_SFmode
+ if (REAL_MODE_FORMAT (GET_MODE (from)) == &arm_bfloat_half_format
+ && REAL_MODE_FORMAT (SFmode) == &ieee_single_format)
+ /* We don't have BF -> TI library functions, use BF -> SF -> TI
+ instead but the BF -> SF conversion can be just a shift, doesn't
+ need to handle sNANs. */
+ {
+ int save_flag_finite_math_only = flag_finite_math_only;
+ flag_finite_math_only = true;
+ from = convert_to_mode (SFmode, from, 0);
+ flag_finite_math_only = save_flag_finite_math_only;
+ expand_fix (to, from, unsignedp);
+ return;
+ }
+#endif
+
/* We can't do it with an insn, so use a library call. But first ensure
that the mode of TO is at least as wide as SImode, since those are the
only library calls we know about. */