This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
fpu/e_expl.c for i686
- To: libc-alpha at sources dot redhat dot com
- Subject: fpu/e_expl.c for i686
- From: Andreas Jaeger <aj at suse dot de>
- Date: 06 May 2001 22:17:28 +0200
- Cc: Jan Hubicka <jh at suse dot cz>
Uli, you comment in sysdeps/i386/fpu/e_expl.S that the code can be
written better for i686. What have you had in mind? I'd like to
optimize the code for i686 and newer systems. The only thing I
considered was changing these instructions:
1: testl $0x200, %eax /* Test sign. */
jz 2f /* If positive, jump. */
fstp %st
fldz /* Set result to 0. */
2:
to these removing one conditional jump:
1: fldz
testl $0x200, %eax /* Test sign. */
fcmovnz %st(1),%st(0)
fstp %st(1)
2:
Changing the assembler file to an inline asm, I also have a problem
that the inline asm can only have one exit point. Is my
transformation ok?
Andreas
============================================================
Index: sysdeps/i386/i686/fpu/e_expl.c
--- sysdeps/i386/i686/fpu/e_expl.c created
+++ sysdeps/i386/i686/fpu/e_expl.c Sun May 6 22:14:16 2001 1.1
@@ -0,0 +1,46 @@
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ *
+ * Adapted for `long double' by Ulrich Drepper <drepper@cygnus.com>.
+ */
+
+#include <math_private.h>
+
+/* e^x = 2^(x * log2l(e)) */
+long double
+__ieee754_expl (long double x)
+{
+ long double res;
+
+/* I added the following ugly construct because expl(+-Inf) resulted
+ in NaN. The ugliness results from the bright minds at Intel.
+ For the i686 the code can be written better.
+ -- drepper@cygnus.com. */
+ asm ("fxam\n" /* Is NaN or +-Inf? */
+ "fstsw %%ax\n"
+ "movb $0x45, %%dh\n"
+ "andb %%ah, %%dh\n"
+ "cmpb $0x05, %%dh\n"
+ "je 1f\n" /* Is +-Inf, jump. */
+ "fldl2e\n"
+ "fmulp\n" /* x * log2(e) */
+ "fld %%st\n"
+ "frndint\n" /* int(x * log2(e)) */
+ "fsubr %%st,%%st(1)\n" /* fract(x * log2(e)) */
+ "fxch\n"
+ "f2xm1\n" /* 2^(fract(x * log2(e))) - 1 */
+ "fld1\n"
+ "faddp\n" /* 2^(fract(x * log2(e))) */
+ "fscale\n" /* e^x */
+ "fstp %%st(1)\n"
+ "jmp 2f\n"
+ "1:\ttestl $0x200, %%eax\n" /* Test sign. */
+ "jz 2f\n" /* If positive, jump. */
+ "fstp %%st\n"
+ "fldz\n" /* Set result to 0. */
+ "2:\t\n"
+ : "=t" (res) : "0" (x) : "ax", "dx");
+
+ return res;
+}
--
Andreas Jaeger
SuSE Labs aj@suse.de
private aj@arthur.inka.de
http://www.suse.de/~aj