Piotr Caban : msvcrt: Call cdecl functions with empty FPU stack in _CI* functions.
Alexandre Julliard
julliard at winehq.org
Tue Nov 28 15:11:04 CST 2017
Module: wine
Branch: master
Commit: ee33d38c5041a8293c64257801572d1c742b0aba
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ee33d38c5041a8293c64257801572d1c742b0aba
Author: Piotr Caban <piotr at codeweavers.com>
Date: Mon Nov 27 20:29:44 2017 +0100
msvcrt: Call cdecl functions with empty FPU stack in _CI* functions.
The FPU stack should be empty on cdecl function call. Failing to do so
breaks GCC 6.4.0 -O2 optimized code.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/msvcrt/math.c | 269 ++++++++++++++++++++++-------------------------------
1 file changed, 111 insertions(+), 158 deletions(-)
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c
index b7288cf..0627bfa 100644
--- a/dlls/msvcrt/math.c
+++ b/dlls/msvcrt/math.c
@@ -593,164 +593,117 @@ double CDECL MSVCRT_tanh( double x )
#if defined(__GNUC__) && defined(__i386__)
-#define FPU_DOUBLE(var) double var; \
- __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var) : )
-#define FPU_DOUBLES(var1,var2) double var1,var2; \
- __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var2) : ); \
- __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var1) : )
-
-/*********************************************************************
- * _CIacos (MSVCRT.@)
- */
-double CDECL _CIacos(void)
-{
- FPU_DOUBLE(x);
- return MSVCRT_acos(x);
-}
-
-/*********************************************************************
- * _CIasin (MSVCRT.@)
- */
-double CDECL _CIasin(void)
-{
- FPU_DOUBLE(x);
- return MSVCRT_asin(x);
-}
-
-/*********************************************************************
- * _CIatan (MSVCRT.@)
- */
-double CDECL _CIatan(void)
-{
- FPU_DOUBLE(x);
- return MSVCRT_atan(x);
-}
-
-/*********************************************************************
- * _CIatan2 (MSVCRT.@)
- */
-double CDECL _CIatan2(void)
-{
- FPU_DOUBLES(x,y);
- return MSVCRT_atan2(x,y);
-}
-
-/*********************************************************************
- * _CIcos (MSVCRT.@)
- */
-double CDECL _CIcos(void)
-{
- FPU_DOUBLE(x);
- return MSVCRT_cos(x);
-}
-
-/*********************************************************************
- * _CIcosh (MSVCRT.@)
- */
-double CDECL _CIcosh(void)
-{
- FPU_DOUBLE(x);
- return MSVCRT_cosh(x);
-}
-
-/*********************************************************************
- * _CIexp (MSVCRT.@)
- */
-double CDECL _CIexp(void)
-{
- FPU_DOUBLE(x);
- return MSVCRT_exp(x);
-}
-
-/*********************************************************************
- * _CIfmod (MSVCRT.@)
- */
-double CDECL _CIfmod(void)
-{
- FPU_DOUBLES(x,y);
- return MSVCRT_fmod(x,y);
-}
-
-/*********************************************************************
- * _CIlog (MSVCRT.@)
- */
-double CDECL _CIlog(void)
-{
- FPU_DOUBLE(x);
- return MSVCRT_log(x);
-}
-
-/*********************************************************************
- * _CIlog10 (MSVCRT.@)
- */
-double CDECL _CIlog10(void)
-{
- FPU_DOUBLE(x);
- return MSVCRT_log10(x);
-}
-
-/*********************************************************************
- * _CIpow (MSVCRT.@)
- */
-double CDECL _CIpow(void)
-{
- FPU_DOUBLES(x,y);
- return MSVCRT_pow(x,y);
-}
-
-/*********************************************************************
- * _CIsin (MSVCRT.@)
- */
-double CDECL _CIsin(void)
-{
- FPU_DOUBLE(x);
- return MSVCRT_sin(x);
-}
-
-/*********************************************************************
- * _CIsinh (MSVCRT.@)
- */
-double CDECL _CIsinh(void)
-{
- FPU_DOUBLE(x);
- return MSVCRT_sinh(x);
-}
-
-/*********************************************************************
- * _CIsqrt (MSVCRT.@)
- */
-double CDECL _CIsqrt(void)
-{
- FPU_DOUBLE(x);
- return MSVCRT_sqrt(x);
-}
-
-/*********************************************************************
- * _CItan (MSVCRT.@)
- */
-double CDECL _CItan(void)
-{
- FPU_DOUBLE(x);
- return MSVCRT_tan(x);
-}
-
-/*********************************************************************
- * _CItanh (MSVCRT.@)
- */
-double CDECL _CItanh(void)
-{
- FPU_DOUBLE(x);
- return MSVCRT_tanh(x);
-}
-
-/*********************************************************************
- * _ftol (MSVCRT.@)
- */
-LONGLONG CDECL MSVCRT__ftol(void)
-{
- FPU_DOUBLE(x);
- return (LONGLONG)x;
-}
+#define CREATE_FPU_FUNC1(name, call) \
+ __ASM_GLOBAL_FUNC(name, \
+ "pushl %ebp\n\t" \
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
+ __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") \
+ "movl %esp, %ebp\n\t" \
+ __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") \
+ "subl $68, %esp\n\t" /* sizeof(double)*8 + sizeof(int) */ \
+ "fstpl (%esp)\n\t" /* store function argument */ \
+ "fwait\n\t" \
+ "movl $1, %ecx\n\t" /* empty FPU stack */ \
+ "1:\n\t" \
+ "fxam\n\t" \
+ "fstsw %ax\n\t" \
+ "and $0x4500, %ax\n\t" \
+ "cmp $0x4100, %ax\n\t" \
+ "je 2f\n\t" \
+ "fstpl (%esp,%ecx,8)\n\t" \
+ "fwait\n\t" \
+ "incl %ecx\n\t" \
+ "jmp 1b\n\t" \
+ "2:\n\t" \
+ "movl %ecx, -4(%ebp)\n\t" \
+ "call " __ASM_NAME( #call ) "\n\t" \
+ "movl -4(%ebp), %ecx\n\t" \
+ "fstpl (%esp)\n\t" /* save result */ \
+ "3:\n\t" /* restore FPU stack */ \
+ "decl %ecx\n\t" \
+ "fldl (%esp,%ecx,8)\n\t" \
+ "cmpl $0, %ecx\n\t" \
+ "jne 3b\n\t" \
+ "leave\n\t" \
+ __ASM_CFI(".cfi_def_cfa %esp,4\n\t") \
+ __ASM_CFI(".cfi_same_value %ebp\n\t") \
+ "ret")
+
+#define CREATE_FPU_FUNC2(name, call) \
+ __ASM_GLOBAL_FUNC(name, \
+ "pushl %ebp\n\t" \
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
+ __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") \
+ "movl %esp, %ebp\n\t" \
+ __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") \
+ "subl $68, %esp\n\t" /* sizeof(double)*8 + sizeof(int) */ \
+ "fstpl 8(%esp)\n\t" /* store function argument */ \
+ "fwait\n\t" \
+ "fstpl (%esp)\n\t" \
+ "fwait\n\t" \
+ "movl $2, %ecx\n\t" /* empty FPU stack */ \
+ "1:\n\t" \
+ "fxam\n\t" \
+ "fstsw %ax\n\t" \
+ "and $0x4500, %ax\n\t" \
+ "cmp $0x4100, %ax\n\t" \
+ "je 2f\n\t" \
+ "fstpl (%esp,%ecx,8)\n\t" \
+ "fwait\n\t" \
+ "incl %ecx\n\t" \
+ "jmp 1b\n\t" \
+ "2:\n\t" \
+ "movl %ecx, -4(%ebp)\n\t" \
+ "call " __ASM_NAME( #call ) "\n\t" \
+ "movl -4(%ebp), %ecx\n\t" \
+ "fstpl 8(%esp)\n\t" /* save result */ \
+ "3:\n\t" /* restore FPU stack */ \
+ "decl %ecx\n\t" \
+ "fldl (%esp,%ecx,8)\n\t" \
+ "cmpl $1, %ecx\n\t" \
+ "jne 3b\n\t" \
+ "leave\n\t" \
+ __ASM_CFI(".cfi_def_cfa %esp,4\n\t") \
+ __ASM_CFI(".cfi_same_value %ebp\n\t") \
+ "ret")
+
+CREATE_FPU_FUNC1(_CIacos, MSVCRT_acos)
+CREATE_FPU_FUNC1(_CIasin, MSVCRT_asin)
+CREATE_FPU_FUNC1(_CIatan, MSVCRT_atan)
+CREATE_FPU_FUNC2(_CIatan2, MSVCRT_atan2)
+CREATE_FPU_FUNC1(_CIcos, MSVCRT_cos)
+CREATE_FPU_FUNC1(_CIcosh, MSVCRT_cosh)
+CREATE_FPU_FUNC1(_CIexp, MSVCRT_exp)
+CREATE_FPU_FUNC2(_CIfmod, MSVCRT_fmod)
+CREATE_FPU_FUNC1(_CIlog, MSVCRT_log)
+CREATE_FPU_FUNC1(_CIlog10, MSVCRT_log10)
+CREATE_FPU_FUNC2(_CIpow, MSVCRT_pow)
+CREATE_FPU_FUNC1(_CIsin, MSVCRT_sin)
+CREATE_FPU_FUNC1(_CIsinh, MSVCRT_sinh)
+CREATE_FPU_FUNC1(_CIsqrt, MSVCRT_sqrt)
+CREATE_FPU_FUNC1(_CItan, MSVCRT_tan)
+CREATE_FPU_FUNC1(_CItanh, MSVCRT_tanh)
+
+__ASM_GLOBAL_FUNC(MSVCRT__ftol,
+ "pushl %ebp\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
+ "movl %esp, %ebp\n\t"
+ __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
+ "subl $12, %esp\n\t" /* sizeof(LONGLONG) + 2*sizeof(WORD) */
+ "fnstcw (%esp)\n\t"
+ "mov (%esp), %ax\n\t"
+ "or $0xc, %ax\n\t"
+ "mov %ax, 2(%esp)\n\t"
+ "fldcw 2(%esp)\n\t"
+ "fistpq 4(%esp)\n\t"
+ "fldcw (%esp)\n\t"
+ "movl 4(%esp), %eax\n\t"
+ "movl 8(%esp), %edx\n\t"
+ "leave\n\t"
+ __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
+ __ASM_CFI(".cfi_same_value %ebp\n\t")
+ "ret")
#endif /* defined(__GNUC__) && defined(__i386__) */
More information about the wine-cvs
mailing list