diff options
author | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-11-22 00:38:30 +0000 |
---|---|---|
committer | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-11-22 00:38:30 +0000 |
commit | 4f5bcdbdf334ba80e3f4890bb752e457601f3e9e (patch) | |
tree | cf1224f63a9636c4333be5cb2d3cabfe2eec233d /gcc/optabs.c | |
parent | 624e1eec9297f70ad0a205f71092eaa6863dc87b (diff) | |
download | gcc-4f5bcdbdf334ba80e3f4890bb752e457601f3e9e.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@107345 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index 6b681a350c1..d764017a5d9 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", |