aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2005-11-22 00:38:30 +0000
committerJoseph Myers <jsm28@gcc.gnu.org>2005-11-22 00:38:30 +0000
commitd773588022f2e3c1bd166658b6c6c8bbba230ddf (patch)
treecf1224f63a9636c4333be5cb2d3cabfe2eec233d /gcc/optabs.c
parent131aeb82d18736392c992c79c2184b2ad16c6190 (diff)
downloadgcc-d773588022f2e3c1bd166658b6c6c8bbba230ddf.zip
gcc-d773588022f2e3c1bd166658b6c6c8bbba230ddf.tar.gz
gcc-d773588022f2e3c1bd166658b6c6c8bbba230ddf.tar.bz2
fp-bit.c (clzusi): New function.
* config/fp-bit.c (clzusi): New function. (si_to_float, usi_to_float): Use it to compute proper shift. (usi_to_float): Preserve guard bits when shifting right. * libgcc-std.ver (GCC_4.2.0): New version. * libgcc2.c (__floatundixf, __floatunditf, __floatundidf, __floatundisf): New functions. * libgcc2.h (__floatundixf, __floatunditf, __floatundidf, __floatundisf): Declare. * mklibgcc.in (lib2funcs): Add _floatundidf, _floatundisf, _floatundixf, and _floatunditf. * optabs.c (expand_float): If target does not define a pattern for signed or unsigned conversion, use an unsigned libcall instead of a signed one. (init_optabs): Initialize ufloat_optab. testsuite: * gcc.c-torture/execute/floatunsisf-1.c: New test. From-SVN: r107345
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 6b681a3..d764017 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -4310,6 +4310,7 @@ expand_float (rtx to, rtx from, int unsignedp)
enum insn_code icode;
rtx target = to;
enum machine_mode fmode, imode;
+ bool can_do_signed = false;
/* Crash now, because we won't be able to decide which mode to use. */
gcc_assert (GET_MODE (from) != VOIDmode);
@@ -4331,8 +4332,14 @@ expand_float (rtx to, rtx from, int unsignedp)
continue;
icode = can_float_p (fmode, imode, unsignedp);
- if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
- icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
+ if (icode == CODE_FOR_nothing && unsignedp)
+ {
+ enum insn_code scode = can_float_p (fmode, imode, 0);
+ if (scode != CODE_FOR_nothing)
+ can_do_signed = true;
+ if (imode != GET_MODE (from))
+ icode = scode, doing_unsigned = 0;
+ }
if (icode != CODE_FOR_nothing)
{
@@ -4353,7 +4360,7 @@ expand_float (rtx to, rtx from, int unsignedp)
/* Unsigned integer, and no way to convert directly.
Convert as signed, then conditionally adjust the result. */
- if (unsignedp)
+ if (unsignedp && can_do_signed)
{
rtx label = gen_label_rtx ();
rtx temp;
@@ -5232,6 +5239,8 @@ init_optabs (void)
/* Conversions. */
init_interclass_conv_libfuncs (sfloat_optab, "float",
MODE_INT, MODE_FLOAT);
+ init_interclass_conv_libfuncs (ufloat_optab, "floatun",
+ MODE_INT, MODE_FLOAT);
init_interclass_conv_libfuncs (sfix_optab, "fix",
MODE_FLOAT, MODE_INT);
init_interclass_conv_libfuncs (ufix_optab, "fixuns",