aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2006-10-25 13:01:14 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2006-10-25 13:01:14 +0000
commitbb7f04236c6c8c1f248f27eb86d9eb486a93c64b (patch)
treea42a7cd31e5e9d2deb0e1ba2a6a9064a8aeaef12 /gcc/optabs.c
parentef984648a15c2c9b8b5127c1ac2e10f3f9793cec (diff)
downloadgcc-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.c44
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);