This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

fpu/e_expl.c for i686



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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]