Hello!
Attached patch expands call to finite(), finitef() and finitel() as
inline i386 asm (and produces the same code as is present in libm for
those functions).
Following testcase:
--cut here--
int test(double a)
{
return finite(a + 2.0);
}
--cut here--
produces (gcc -O2 -fomit-frame-pointer):
test:
subl $12, %esp
movl $-1048577, %eax
flds .LC0
faddl 16(%esp)
fstpl (%esp)
movl 4(%esp), %edx
addl $12, %esp
subl %edx, %eax
xorl %edx, %eax
shrl $31, %eax
ret
The patch also works for -mfpmath=sse:
test:
subl $12, %esp
movl $-1048577, %eax
movsd .LC0, %xmm0
addsd 16(%esp), %xmm0
movsd %xmm0, (%esp)
movl 4(%esp), %edx
addl $12, %esp
subl %edx, %eax
xorl %edx, %eax
shrl $31, %eax
ret
Regarding the implementation, by representing "finite" optab as a
conversion optab, existing infrastructure that handles conversion
optabs could be used with minimum middle-end changes.
Patch was bootstrapped and regression tested on i686-pc-linux-gnu for
all default languages. OK for mainline?
2007-01-25 Uros Bizjak <ubizjak@gmail.com>
* optabs.h (enum convert_optab_index): Add new COI_finite.
(finite_optab): Define corresponding macro.
* optabs.c (init_optabs): Initialize finite_optab.
* genopinit.c (optabs): Implement finite_optab using finite?f?i2
patterns.
* builtins.c (expand_builtin_int_roundingfn_2): Handle
BUILT_IN_FINITE{,F,L} using finite_optab. Add check_errno boolean
and clear it for BUILT_IN_FINITE{,F,L}. Do not expand optab when
check_errno and flag_errno_math are both set.
(expand_builtin): Expand BUILT_IN_FINITE{,F,L} using
expand_builtin_int_roundingfn_2.
* config/i386/i386.md (finite<mode>si2) New expander to implement
finite, finitef and finitel built-in functions as inline asm.
testsuite/ChangeLog:
2007-01-25 Uros Bizjak <ubizjak@gmail.com>
* gcc.dg/builtins-63.c: New test.
Uros.