diff options
author | Richard Guenther <rguenther@suse.de> | 2006-10-25 13:01:14 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2006-10-25 13:01:14 +0000 |
commit | bb7f04236c6c8c1f248f27eb86d9eb486a93c64b (patch) | |
tree | a42a7cd31e5e9d2deb0e1ba2a6a9064a8aeaef12 /gcc/optabs.c | |
parent | ef984648a15c2c9b8b5127c1ac2e10f3f9793cec (diff) | |
download | gcc-bb7f04236c6c8c1f248f27eb86d9eb486a93c64b.zip gcc-bb7f04236c6c8c1f248f27eb86d9eb486a93c64b.tar.gz gcc-bb7f04236c6c8c1f248f27eb86d9eb486a93c64b.tar.bz2 |
optabs.h (enum optab_index): Remove OTI_lrint.
2006-10-25 Richard Guenther <rguenther@suse.de>
* optabs.h (enum optab_index): Remove OTI_lrint.
(enum convert_optab_index): Add COI_lrint.
(lrint_optab): Adjust.
(expand_sfix_optab): Declare.
* optabs.c (expand_sfix_optab): New function.
(init_optabs): Init lrint_optab as conversion optab.
* genopinit.c (lrint_optab): Change to a conversion optab.
* builtins.c (expand_builtin_int_roundingfn_2): Adjust to
expansion via conversion optab.
* config/i386/i386.md (*fistdi2_1): Remove
flag_unsafe_math_optimizations guard.
(fistdi2, fistdi2_with_temp, *fist<mode>2_1, fist<mode>2,
fist<mode>2_with_temp): Likewise.
(lrint<mode>2): Split into...
(lrintxf<mode>2): ... x87 part
(lrint<mode>di2, lrint<mode>si2): ... and SSE parts.
* config/i386/sse.md (sse_cvtss2si_2, sse_cvtss2_siq_2,
sse2_cvtsd2si_2, sse2_cvtsd2siq_2): New insns for
UNSPEC_FIX_NOTRUNC matching non-vector float modes.
* doc/md.texi (lrintMN2): Document.
From-SVN: r118029
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index 12fd34e..11cacae 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -4861,6 +4861,46 @@ expand_fix (rtx to, rtx from, int unsignedp) convert_move (to, target, 0); } } + +/* Generate code to convert FROM to fixed point and store in TO. FROM + must be floating point, TO must be signed. Use the conversion optab + TAB to do the conversion. */ + +bool +expand_sfix_optab (rtx to, rtx from, convert_optab tab) +{ + enum insn_code icode; + rtx target = to; + enum machine_mode fmode, imode; + + /* We first try to find a pair of modes, one real and one integer, at + least as wide as FROM and TO, respectively, in which we can open-code + this conversion. If the integer mode is wider than the mode of TO, + we can do the conversion either signed or unsigned. */ + + for (fmode = GET_MODE (from); fmode != VOIDmode; + fmode = GET_MODE_WIDER_MODE (fmode)) + for (imode = GET_MODE (to); imode != VOIDmode; + imode = GET_MODE_WIDER_MODE (imode)) + { + icode = tab->handlers[imode][fmode].insn_code; + if (icode != CODE_FOR_nothing) + { + if (fmode != GET_MODE (from)) + from = convert_to_mode (fmode, from, 0); + + if (imode != GET_MODE (to)) + target = gen_reg_rtx (imode); + + emit_unop_insn (icode, target, from, UNKNOWN); + if (target != to) + convert_move (to, target, 0); + return true; + } + } + + return false; +} /* Report whether we have an instruction to perform the operation specified by CODE on operands of mode MODE. */ @@ -5266,7 +5306,6 @@ init_optabs (void) btrunc_optab = init_optab (UNKNOWN); nearbyint_optab = init_optab (UNKNOWN); rint_optab = init_optab (UNKNOWN); - lrint_optab = init_optab (UNKNOWN); sincos_optab = init_optab (UNKNOWN); sin_optab = init_optab (UNKNOWN); asin_optab = init_optab (UNKNOWN); @@ -5325,6 +5364,7 @@ init_optabs (void) ufixtrunc_optab = init_convert_optab (UNKNOWN); sfloat_optab = init_convert_optab (FLOAT); ufloat_optab = init_convert_optab (UNSIGNED_FLOAT); + lrint_optab = init_convert_optab (UNKNOWN); for (i = 0; i < NUM_MACHINE_MODES; i++) { @@ -5444,6 +5484,8 @@ init_optabs (void) MODE_DECIMAL_FLOAT, MODE_INT); init_interclass_conv_libfuncs (ufloat_optab, "floatuns", MODE_INT, MODE_DECIMAL_FLOAT); + init_interclass_conv_libfuncs (lrint_optab, "lrint", + MODE_INT, MODE_FLOAT); /* sext_optab is also used for FLOAT_EXTEND. */ init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true); |