svn commit: trunk/uClibc/libm

vda at uclibc.org vda at uclibc.org
Mon Feb 9 13:10:13 UTC 2009


Author: vda
Date: 2009-02-09 13:10:12 +0000 (Mon, 09 Feb 2009)
New Revision: 25273

Log:
Hand-optimize wrappers on i386:

-83 ec 10               sub    $0x10,%esp
-db 6c 24 14            fldt   0x14(%esp)
-dd 5c 24 08            fstpl  0x8(%esp)
-dd 44 24 08            fldl   0x8(%esp)
-dd 1c 24               fstpl  (%esp)
-e8 fc ff ff ff         call   __GI_trunc
-83 c4 10               add    $0x10,%esp
+db 6c 24 04            fldt   0x4(%esp)
+dd 5c 24 04            fstpl  0x4(%esp)
+e9 fc ff ff ff         jmp    __GI_trunc
 c3                     ret

    text           data     bss     dec     hex filename
-  42749            176       4   42929    a7b1 lib/libm-0.9.30-svn.so
+  42085            176       4   42265    a519 lib/libm-0.9.30-svn.so



Modified:
   trunk/uClibc/libm/ldouble_wrappers.c


Changeset:
Modified: trunk/uClibc/libm/ldouble_wrappers.c
===================================================================
--- trunk/uClibc/libm/ldouble_wrappers.c	2009-02-09 13:09:55 UTC (rev 25272)
+++ trunk/uClibc/libm/ldouble_wrappers.c	2009-02-09 13:10:12 UTC (rev 25273)
@@ -16,7 +16,72 @@
 #include "math.h"
 #include <complex.h>
 
+#define STRINGIZE(s) #s
 
+#define WRAPPER1(func) \
+long double func##l(long double x) \
+{ \
+	return (long double) func((double) x); \
+}
+
+#define int_WRAPPER1(func) \
+int func##l(long double x) \
+{ \
+	return func((double) x); \
+}
+
+#if defined __i386__ && defined __OPTIMIZE__
+# undef WRAPPER1
+# undef int_WRAPPER1
+/* gcc 4.3.1 generates really ugly code with redundant pair of store/load:
+ *	sub    $0x10,%esp
+ *	fldt	0x14(%esp)
+ *	fstpl	0x8(%esp)
+ *	fldl	0x8(%esp) <-- ??
+ *	fstpl	(%esp)    <-- ??
+ *	call	function
+ *	add	$0x10,%esp
+ *	ret
+ * I can hope newer gcc will eliminate that. However, I don't think
+ * it will be smart enough to reuse argument stack space and use
+ * jump instead of call. Let's do it by hand.
+ * The asm below loads long double x into st(0), then stores it back
+ * to the same location as a double. At this point, stack looks exactly
+ * as "double func(double)" expects it to be.
+ * The return value is returned in st(0) per ABI in both cases (returning
+ * a long double or returning a double). So we can simply jump to func.
+ * Using __GI_func in jump to make optimized intra-library jump.
+ * gcc will still generate a useless "ret" after asm. Oh well...
+ */
+# define WRAPPER1(func) \
+long double func##l(long double x) \
+{ \
+	long double fp_top; \
+	__asm ( \
+	"	fldt	%1\n" \
+	"	fstpl	%1\n" \
+	"	jmp	" STRINGIZE(__GI_##func) "\n" \
+	: "=t" (fp_top) \
+	: "m" (x) \
+	); \
+	return fp_top; \
+}
+# define int_WRAPPER1(func) \
+int func##l(long double x) \
+{ \
+	int ret; \
+	__asm ( \
+	"	fldt	%1\n" \
+	"	fstpl	%1\n" \
+	"	jmp	" STRINGIZE(__GI_##func) "\n" \
+	: "=a" (ret) \
+	: "m" (x) \
+	); \
+	return ret; \
+}
+#endif /* __i386__ */
+
+
 /* Implement the following, as defined by SuSv3 */
 #if 0
 long double acoshl(long double);
@@ -79,31 +144,19 @@
 #endif
 
 #ifdef L_acoshl
-long double acoshl (long double x)
-{
-	return (long double) acosh( (double)x );
-}
+WRAPPER1(acosh)
 #endif
 
 #ifdef L_acosl
-long double acosl (long double x)
-{
-	return (long double) acos( (double)x );
-}
+WRAPPER1(acos)
 #endif
 
 #ifdef L_asinhl
-long double asinhl (long double x)
-{
-	return (long double) asinh( (double)x );
-}
+WRAPPER1(asinh)
 #endif
 
 #ifdef L_asinl
-long double asinl (long double x)
-{
-	return (long double) asin( (double)x );
-}
+WRAPPER1(asin)
 #endif
 
 #ifdef L_atan2l
@@ -114,17 +167,11 @@
 #endif
 
 #ifdef L_atanhl
-long double atanhl (long double x)
-{
-	return (long double) atanh( (double)x );
-}
+WRAPPER1(atanh)
 #endif
 
 #ifdef L_atanl
-long double atanl (long double x)
-{
-	return (long double) atan( (double)x );
-}
+WRAPPER1(atan)
 #endif
 
 #ifdef L_cargl
@@ -135,17 +182,11 @@
 #endif
 
 #ifdef L_cbrtl
-long double cbrtl (long double x)
-{
-	return (long double) cbrt( (double)x );
-}
+WRAPPER1(cbrt)
 #endif
 
 #ifdef L_ceill
-long double ceill (long double x)
-{
-	return (long double) ceil( (double)x );
-}
+WRAPPER1(ceil)
 #endif
 
 #ifdef L_copysignl
@@ -156,59 +197,35 @@
 #endif
 
 #ifdef L_coshl
-long double coshl (long double x)
-{
-	return (long double) cosh( (double)x );
-}
+WRAPPER1(cosh)
 #endif
 
 #ifdef L_cosl
-long double cosl (long double x)
-{
-	return (long double) cos( (double)x );
-}
+WRAPPER1(cos)
 #endif
 
 #ifdef L_erfcl
-long double erfcl (long double x)
-{
-	return (long double) erfc( (double)x );
-}
+WRAPPER1(erfc)
 #endif
 
 #ifdef L_erfl
-long double erfl (long double x)
-{
-	return (long double) erf( (double)x );
-}
+WRAPPER1(erf)
 #endif
 
 #ifdef L_exp2l
-long double exp2l (long double x)
-{
-	return (long double) exp2( (double)x );
-}
+WRAPPER1(exp2)
 #endif
 
 #ifdef L_expl
-long double expl (long double x)
-{
-	return (long double) exp( (double)x );
-}
+WRAPPER1(exp)
 #endif
 
 #ifdef L_expm1l
-long double expm1l (long double x)
-{
-	return (long double) expm1( (double)x );
-}
+WRAPPER1(expm1)
 #endif
 
 #ifdef L_fabsl
-long double fabsl (long double x)
-{
-	return (long double) fabs( (double)x );
-}
+WRAPPER1(fabs)
 #endif
 
 #ifdef L_fdiml
@@ -219,10 +236,7 @@
 #endif
 
 #ifdef L_floorl
-long double floorl (long double x)
-{
-	return (long double) floor( (double)x );
-}
+WRAPPER1(floor)
 #endif
 
 #ifdef L_fmal
@@ -268,10 +282,7 @@
 #endif
 
 #ifdef L_ilogbl
-int ilogbl (long double x)
-{
-	return (long double) ilogb( (double)x );
-}
+int_WRAPPER1(ilogb)
 #endif
 
 #ifdef L_ldexpl
@@ -282,10 +293,7 @@
 #endif
 
 #ifdef L_lgammal
-long double lgammal (long double x)
-{
-	return (long double) lgamma( (double)x );
-}
+WRAPPER1(lgamma)
 #endif
 
 #ifdef L_llrintl
@@ -303,38 +311,23 @@
 #endif
 
 #ifdef L_log10l
-long double log10l (long double x)
-{
-	return (long double) log10( (double)x );
-}
+WRAPPER1(log10)
 #endif
 
 #ifdef L_log1pl
-long double log1pl (long double x)
-{
-	return (long double) log1p( (double)x );
-}
+WRAPPER1(log1p)
 #endif
 
 #ifdef L_log2l
-long double log2l (long double x)
-{
-	return (long double) log2( (double)x );
-}
+WRAPPER1(log2)
 #endif
 
 #ifdef L_logbl
-long double logbl (long double x)
-{
-	return (long double) logb( (double)x );
-}
+WRAPPER1(logb)
 #endif
 
 #ifdef L_logl
-long double logl (long double x)
-{
-	return (long double) log( (double)x );
-}
+WRAPPER1(log)
 #endif
 
 #ifdef L_lrintl
@@ -362,10 +355,7 @@
 #endif
 
 #ifdef L_nearbyintl
-long double nearbyintl (long double x)
-{
-	return (long double) nearbyint( (double)x );
-}
+WRAPPER1(nearbyint)
 #endif
 
 #ifdef L_nextafterl
@@ -404,17 +394,11 @@
 #endif
 
 #ifdef L_rintl
-long double rintl (long double x)
-{
-	return (long double) rint( (double)x );
-}
+WRAPPER1(rint)
 #endif
 
 #ifdef L_roundl
-long double roundl (long double x)
-{
-	return (long double) round( (double)x );
-}
+WRAPPER1(round)
 #endif
 
 #ifdef L_scalblnl
@@ -432,90 +416,54 @@
 #endif
 
 #ifdef L_sinhl
-long double sinhl (long double x)
-{
-	return (long double) sinh( (double)x );
-}
+WRAPPER1(sinh)
 #endif
 
 #ifdef L_sinl
-long double sinl (long double x)
-{
-	return (long double) sin( (double)x );
-}
+WRAPPER1(sin)
 #endif
 
 #ifdef L_sqrtl
-long double sqrtl (long double x)
-{
-	return (long double) sqrt( (double)x );
-}
+WRAPPER1(sqrt)
 #endif
 
 #ifdef L_tanhl
-long double tanhl (long double x)
-{
-	return (long double) tanh( (double)x );
-}
+WRAPPER1(tanh)
 #endif
 
 #ifdef L_tanl
-long double tanl (long double x)
-{
-	return (long double) tan( (double)x );
-}
+WRAPPER1(tan)
 #endif
 
 #ifdef L_tgammal
-long double tgammal (long double x)
-{
-	return (long double) tgamma( (double)x );
-}
+WRAPPER1(tgamma)
 #endif
 
 #ifdef L_truncl
-long double truncl (long double x)
-{
-	return (long double) trunc( (double)x );
-}
+WRAPPER1(trunc)
 #endif
 
 #ifdef __DO_C99_MATH__
 
 #ifdef L_fpclassifyl
-int __fpclassifyl (long double x)
-{
-	return __fpclassify ( (double) x );
-}
+int_WRAPPER1(__fpclassify);
 #endif
 
 #ifdef L_finitel
-int __finitel (long double x)
-{
-	return __finite ( (double)x );
-}
+int_WRAPPER1(__finite)
 #endif
 
 #ifdef L___signbitl
-int __signbitl (long double x)
-{
-	return __signbit ( (double)x );
-}
+int_WRAPPER1(__signbit)
 #endif
 
 #ifdef L_isnanl
-int __isnanl (long double x)
-{
-	return __isnan ( (double)x );
-}
+int_WRAPPER1(__isnan)
 libm_hidden_def(__isnanl)
 #endif
 
 #ifdef L_isinfl
-int __isinfl (long double x)
-{
-	return __isinf ( (double)x );
-}
+int_WRAPPER1(__isinf)
 libm_hidden_def(__isinfl)
 #endif
 



More information about the uClibc-cvs mailing list