summaryrefslogtreecommitdiff
path: root/libm/ldouble_wrappers.c
diff options
context:
space:
mode:
Diffstat (limited to 'libm/ldouble_wrappers.c')
-rw-r--r--libm/ldouble_wrappers.c73
1 files changed, 49 insertions, 24 deletions
diff --git a/libm/ldouble_wrappers.c b/libm/ldouble_wrappers.c
index 6e253fad1..a9324cece 100644
--- a/libm/ldouble_wrappers.c
+++ b/libm/ldouble_wrappers.c
@@ -23,18 +23,29 @@ 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); \
}
+#define long_WRAPPER1(func) \
+long func##l(long double x) \
+{ \
+ return func((double) x); \
+}
+#define long_long_WRAPPER1(func) \
+long long func##l(long double x) \
+{ \
+ return func((double) x); \
+}
#if defined __i386__ && defined __OPTIMIZE__
# undef WRAPPER1
# undef int_WRAPPER1
+# undef long_WRAPPER1
+# undef long_long_WRAPPER1
/* gcc 4.3.1 generates really ugly code with redundant pair of store/load:
- * sub $0x10,%esp
+ * sub $0x10,%esp
* fldt 0x14(%esp)
* fstpl 0x8(%esp)
* fldl 0x8(%esp) <-- ??
@@ -46,8 +57,8 @@ int func##l(long double x) \
* 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.
+ * to the same location, but 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.
@@ -56,15 +67,15 @@ int func##l(long double x) \
# define WRAPPER1(func) \
long double func##l(long double x) \
{ \
- long double fp_top; \
+ long double st_top; \
__asm ( \
" fldt %1\n" \
" fstpl %1\n" \
" jmp " STRINGIZE(__GI_##func) "\n" \
- : "=t" (fp_top) \
+ : "=t" (st_top) \
: "m" (x) \
); \
- return fp_top; \
+ return st_top; \
}
# define int_WRAPPER1(func) \
int func##l(long double x) \
@@ -79,7 +90,33 @@ int func##l(long double x) \
); \
return ret; \
}
-#endif /* __i386__ */
+# define long_WRAPPER1(func) \
+long func##l(long double x) \
+{ \
+ long ret; \
+ __asm ( \
+ " fldt %1\n" \
+ " fstpl %1\n" \
+ " jmp " STRINGIZE(__GI_##func) "\n" \
+ : "=a" (ret) \
+ : "m" (x) \
+ ); \
+ return ret; \
+}
+# define long_long_WRAPPER1(func) \
+long long func##l(long double x) \
+{ \
+ long long ret; \
+ __asm ( \
+ " fldt %1\n" \
+ " fstpl %1\n" \
+ " jmp " STRINGIZE(__GI_##func) "\n" \
+ : "=A" (ret) \
+ : "m" (x) \
+ ); \
+ return ret; \
+}
+#endif /* __i386__ && __OPTIMIZE__ */
/* Implement the following, as defined by SuSv3 */
@@ -297,17 +334,11 @@ WRAPPER1(lgamma)
#endif
#ifdef L_llrintl
-long long llrintl (long double x)
-{
- return llrint( (double)x );
-}
+long_long_WRAPPER1(llrint)
#endif
#ifdef L_llroundl
-long long llroundl (long double x)
-{
- return llround( (double)x );
-}
+long_long_WRAPPER1(llround)
#endif
#ifdef L_log10l
@@ -331,17 +362,11 @@ WRAPPER1(log)
#endif
#ifdef L_lrintl
-long lrintl (long double x)
-{
- return lrint( (double)x );
-}
+long_WRAPPER1(lrint)
#endif
#ifdef L_lroundl
-long lroundl (long double x)
-{
- return lround( (double)x );
-}
+long_WRAPPER1(lround)
#endif
#ifdef L_modfl