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
This commit is contained in:
Richard Guenther 2006-10-25 13:01:14 +00:00 committed by Richard Biener
parent ef984648a1
commit bb7f04236c
8 changed files with 171 additions and 57 deletions

View File

@ -1,3 +1,27 @@
2006-10-25 Richard Guenther <rguenther@suse.de>
PR target/28803
* 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.
2006-10-25 Uros Bizjak <uros@kss-loka.si>
PR target/28909

View File

@ -2320,7 +2320,7 @@ expand_builtin_int_roundingfn (tree exp, rtx target, rtx subtarget)
static rtx
expand_builtin_int_roundingfn_2 (tree exp, rtx target, rtx subtarget)
{
optab builtin_optab;
convert_optab builtin_optab;
rtx op0, insns;
tree fndecl = get_callee_fndecl (exp);
tree arglist = TREE_OPERAND (exp, 1);
@ -2348,45 +2348,37 @@ expand_builtin_int_roundingfn_2 (tree exp, rtx target, rtx subtarget)
/* Make a suitable register to place result in. */
mode = TYPE_MODE (TREE_TYPE (exp));
/* Before working hard, check whether the instruction is available. */
if (builtin_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
target = gen_reg_rtx (mode);
/* Wrap the computation of the argument in a SAVE_EXPR, as we may
need to expand the argument again. This way, we will not perform
side-effects more the once. */
narg = builtin_save_expr (arg);
if (narg != arg)
{
target = gen_reg_rtx (mode);
/* Wrap the computation of the argument in a SAVE_EXPR, as we may
need to expand the argument again. This way, we will not perform
side-effects more the once. */
narg = builtin_save_expr (arg);
if (narg != arg)
{
arg = narg;
arglist = build_tree_list (NULL_TREE, arg);
exp = build_function_call_expr (fndecl, arglist);
}
op0 = expand_expr (arg, subtarget, VOIDmode, 0);
start_sequence ();
/* Compute into TARGET.
Set TARGET to wherever the result comes back. */
target = expand_unop (mode, builtin_optab, op0, target, 0);
if (target != 0)
{
/* Output the entire sequence. */
insns = get_insns ();
end_sequence ();
emit_insn (insns);
return target;
}
/* If we were unable to expand via the builtin, stop the sequence
(without outputting the insns) and call to the library function
with the stabilized argument list. */
end_sequence ();
arg = narg;
arglist = build_tree_list (NULL_TREE, arg);
exp = build_function_call_expr (fndecl, arglist);
}
op0 = expand_expr (arg, subtarget, VOIDmode, 0);
start_sequence ();
if (expand_sfix_optab (target, op0, builtin_optab))
{
/* Output the entire sequence. */
insns = get_insns ();
end_sequence ();
emit_insn (insns);
return target;
}
/* If we were unable to expand via the builtin, stop the sequence
(without outputting the insns) and call to the library function
with the stabilized argument list. */
end_sequence ();
target = expand_call (exp, target, target == const0_rtx);
return target;

View File

@ -17205,7 +17205,6 @@
(unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
UNSPEC_FIST))]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations
&& !(reload_completed || reload_in_progress)"
"#"
"&& 1"
@ -17229,8 +17228,7 @@
(unspec:DI [(match_operand:XF 1 "register_operand" "f")]
UNSPEC_FIST))
(clobber (match_scratch:XF 2 "=&1f"))]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
"TARGET_USE_FANCY_MATH_387"
"* return output_fix_trunc (insn, operands, 0);"
[(set_attr "type" "fpspc")
(set_attr "mode" "DI")])
@ -17241,8 +17239,7 @@
UNSPEC_FIST))
(clobber (match_operand:DI 2 "memory_operand" "=m,m"))
(clobber (match_scratch:XF 3 "=&1f,&1f"))]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
"TARGET_USE_FANCY_MATH_387"
"#"
[(set_attr "type" "fpspc")
(set_attr "mode" "DI")])
@ -17275,7 +17272,6 @@
(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
UNSPEC_FIST))]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations
&& !(reload_completed || reload_in_progress)"
"#"
"&& 1"
@ -17293,8 +17289,7 @@
[(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
UNSPEC_FIST))]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
"TARGET_USE_FANCY_MATH_387"
"* return output_fix_trunc (insn, operands, 0);"
[(set_attr "type" "fpspc")
(set_attr "mode" "<MODE>")])
@ -17304,8 +17299,7 @@
(unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
UNSPEC_FIST))
(clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
"TARGET_USE_FANCY_MATH_387"
"#"
[(set_attr "type" "fpspc")
(set_attr "mode" "<MODE>")])
@ -17331,13 +17325,25 @@
UNSPEC_FIST))]
"")
(define_expand "lrint<mode>2"
(define_expand "lrintxf<mode>2"
[(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
UNSPEC_FIST))]
"TARGET_USE_FANCY_MATH_387
&& (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
&& flag_unsafe_math_optimizations"
(unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
UNSPEC_FIST))]
"TARGET_USE_FANCY_MATH_387"
"")
(define_expand "lrint<mode>di2"
[(set (match_operand:DI 0 "nonimmediate_operand" "")
(unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
UNSPEC_FIX_NOTRUNC))]
"SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
"")
(define_expand "lrint<mode>si2"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
(unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
UNSPEC_FIX_NOTRUNC))]
"SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
"")
;; Rounding mode control word calculation could clobber FLAGS_REG.

View File

@ -974,6 +974,16 @@
(set_attr "athlon_decode" "double,vector")
(set_attr "mode" "SI")])
(define_insn "sse_cvtss2si_2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(unspec:SI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
UNSPEC_FIX_NOTRUNC))]
"TARGET_SSE"
"cvtss2si\t{%1, %0|%0, %1}"
[(set_attr "type" "sseicvt")
(set_attr "athlon_decode" "double,vector")
(set_attr "mode" "SI")])
(define_insn "sse_cvtss2siq"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(unspec:DI
@ -987,6 +997,16 @@
(set_attr "athlon_decode" "double,vector")
(set_attr "mode" "DI")])
(define_insn "sse_cvtss2siq_2"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(unspec:DI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
UNSPEC_FIX_NOTRUNC))]
"TARGET_SSE && TARGET_64BIT"
"cvtss2siq\t{%1, %0|%0, %1}"
[(set_attr "type" "sseicvt")
(set_attr "athlon_decode" "double,vector")
(set_attr "mode" "DI")])
(define_insn "sse_cvttss2si"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(fix:SI
@ -1932,6 +1952,16 @@
(set_attr "athlon_decode" "double,vector")
(set_attr "mode" "SI")])
(define_insn "sse2_cvtsd2si_2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(unspec:SI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
UNSPEC_FIX_NOTRUNC))]
"TARGET_SSE2"
"cvtsd2si\t{%1, %0|%0, %1}"
[(set_attr "type" "sseicvt")
(set_attr "athlon_decode" "double,vector")
(set_attr "mode" "SI")])
(define_insn "sse2_cvtsd2siq"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(unspec:DI
@ -1945,6 +1975,16 @@
(set_attr "athlon_decode" "double,vector")
(set_attr "mode" "DI")])
(define_insn "sse2_cvtsd2siq_2"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(unspec:DI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
UNSPEC_FIX_NOTRUNC))]
"TARGET_SSE2 && TARGET_64BIT"
"cvtsd2siq\t{%1, %0|%0, %1}"
[(set_attr "type" "sseicvt")
(set_attr "athlon_decode" "double,vector")
(set_attr "mode" "DI")])
(define_insn "sse2_cvttsd2si"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(fix:SI

View File

@ -3702,6 +3702,12 @@ corresponds to the C data type @code{double} and the @code{rintf}
built-in function uses the mode which corresponds to the C data
type @code{float}.
@cindex @code{lrint@var{m}@var{n}2}
@item @samp{lrint@var{m}@var{n}2}
Convert operand 1 (valid for floating point mode @var{m}) to fixed
point mode @var{n} as a signed number according to the current
rounding mode and store in operand 0 (which has mode @var{n}).
@cindex @code{copysign@var{m}3} instruction pattern
@item @samp{copysign@var{m}3}
Store a value with the magnitude of operand 1 and the sign of operand

View File

@ -127,7 +127,7 @@ static const char * const optabs[] =
"btrunc_optab->handlers[$A].insn_code = CODE_FOR_$(btrunc$a2$)",
"nearbyint_optab->handlers[$A].insn_code = CODE_FOR_$(nearbyint$a2$)",
"rint_optab->handlers[$A].insn_code = CODE_FOR_$(rint$a2$)",
"lrint_optab->handlers[$A].insn_code = CODE_FOR_$(lrint$a2$)",
"lrint_optab->handlers[$B][$A].insn_code = CODE_FOR_$(lrint$F$a$I$b2$)",
"sincos_optab->handlers[$A].insn_code = CODE_FOR_$(sincos$a3$)",
"sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)",
"asin_optab->handlers[$A].insn_code = CODE_FOR_$(asin$a2$)",

View File

@ -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);

View File

@ -196,7 +196,6 @@ enum optab_index
OTI_round,
OTI_nearbyint,
OTI_rint,
OTI_lrint,
/* Tangent */
OTI_tan,
/* Inverse tangent */
@ -345,7 +344,6 @@ extern GTY(()) optab optab_table[OTI_MAX];
#define round_optab (optab_table[OTI_round])
#define nearbyint_optab (optab_table[OTI_nearbyint])
#define rint_optab (optab_table[OTI_rint])
#define lrint_optab (optab_table[OTI_lrint])
#define tan_optab (optab_table[OTI_tan])
#define atan_optab (optab_table[OTI_atan])
#define copysign_optab (optab_table[OTI_copysign])
@ -407,6 +405,8 @@ enum convert_optab_index
COI_sfloat,
COI_ufloat,
COI_lrint,
COI_MAX
};
@ -421,6 +421,7 @@ extern GTY(()) convert_optab convert_optab_table[COI_MAX];
#define ufixtrunc_optab (convert_optab_table[COI_ufixtrunc])
#define sfloat_optab (convert_optab_table[COI_sfloat])
#define ufloat_optab (convert_optab_table[COI_ufloat])
#define lrint_optab (convert_optab_table[COI_lrint])
/* These arrays record the insn_code of insns that may be needed to
perform input and output reloads of special objects. They provide a
@ -597,6 +598,9 @@ extern void expand_float (rtx, rtx, int);
/* Generate code for a FIX_EXPR. */
extern void expand_fix (rtx, rtx, int);
/* Generate code for float to integral conversion. */
extern bool expand_sfix_optab (rtx, rtx, convert_optab);
/* Return tree if target supports vector operations for COND_EXPR. */
bool expand_vec_cond_expr_p (tree, enum machine_mode);