Fixing ilogb()
Stefan Farfeleder
stefanf at FreeBSD.org
Mon May 10 08:38:10 PDT 2004
On Sun, May 09, 2004 at 09:44:03PM +1000, Bruce Evans wrote:
> % Index: src/lib/msun/i387/s_ilogb.S
> % ===================================================================
> % RCS file: /usr/home/ncvs/src/lib/msun/i387/s_ilogb.S,v
> % retrieving revision 1.8
> % diff -u -r1.8 s_ilogb.S
> % --- src/lib/msun/i387/s_ilogb.S 6 Jun 2000 12:12:36 -0000 1.8
> % +++ src/lib/msun/i387/s_ilogb.S 8 May 2004 18:57:27 -0000
> % @@ -43,11 +43,27 @@
> % subl $4,%esp
> %
> % fldl 8(%ebp)
> % + fxam
> % + fnstsw %ax
> % + sahf
>
> This is the main runtime overhead. I think it can mostly be avoided by
> checking the return value. ilogb() can only be INT_MIN after overflow
> or other conversion errors (check this). There 3 cases:
> - logb(0) = -Inf; fistpl(-Inf) = INT_MIN + IE
> - logb(Inf) = Inf; fistpl(-Inf) = INT_MIN + IE
> - logb(NaN) = same NaN; fistpl(NaN) = INT_MIN + IE
> After finding one of these rare cases, the exact case still needs to be
> determined by looking at the original value or the result of fxtract.
> Then fucom with 0 should be a faster way to do the classification. A
> full classification is not needed sice denormals are not special here
> and unsupported formats are unsupported here too.
Thanks for your comments, Bruce. A revised patch is attached, it only adds two
instructions in the common case.
<snip>
> % + movl $0x7fffffff,%eax /* FP_ILOGBNAN, INT_MAX */
>
> Style bugs: some comments could be improved, but won't be needed when
> <machine/_limits.h> is used.
Unfortunately <math.h> cannot be included for FP_ILOGB{0,NAN}, so I've
duplicated those #defines for now. Any suggestions? Move them to another/new
header instead?
Cheers,
Stefan
-------------- next part --------------
Index: src/lib/msun/i387/s_ilogb.S
===================================================================
RCS file: /usr/home/ncvs/src/lib/msun/i387/s_ilogb.S,v
retrieving revision 1.8
diff -I.svn -u -r1.8 s_ilogb.S
--- src/lib/msun/i387/s_ilogb.S 6 Jun 2000 12:12:36 -0000 1.8
+++ src/lib/msun/i387/s_ilogb.S 10 May 2004 15:24:43 -0000
@@ -33,10 +33,15 @@
* J.T. Conklin (jtc at wimsey.com), Winning Strategies, Inc.
*/
+#include <machine/_limits.h>
#include <machine/asm.h>
RCSID("$FreeBSD: src/lib/msun/i387/s_ilogb.S,v 1.8 2000/06/06 12:12:36 bde Exp $")
+#define FP_ILOGB0 (-__INT_MAX)
+#define FP_ILOGBNAN __INT_MAX
+#define FP_ILOGBINF __INT_MAX
+
ENTRY(ilogb)
pushl %ebp
movl %esp,%ebp
@@ -44,10 +49,35 @@
fldl 8(%ebp)
fxtract
- fstp %st
+ fstp %st(0)
fistpl -4(%ebp)
movl -4(%ebp),%eax
+ /* fistpl yields __INT_MIN for NaN, Inf and 0. */
+ cmpl $__INT_MIN,%eax
+ je .L2
+
+.L1:
leave
ret
+
+.L2:
+ fldl 8(%ebp)
+ fldz
+ fucompp
+ fnstsw %ax
+ sahf
+ jp .L3
+ jz .L4
+
+ movl $FP_ILOGBINF,%eax
+ jmp .L1
+
+.L3:
+ movl $FP_ILOGBNAN,%eax
+ jmp .L1
+
+.L4:
+ movl $FP_ILOGB0,%eax
+ jmp .L1
More information about the freebsd-standards
mailing list