mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-01 12:06:32 +00:00
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@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a7ba456587
commit
ee33d38c50
1 changed files with 108 additions and 155 deletions
|
@ -593,164 +593,117 @@ double CDECL MSVCRT_tanh( double x )
|
||||||
|
|
||||||
#if defined(__GNUC__) && defined(__i386__)
|
#if defined(__GNUC__) && defined(__i386__)
|
||||||
|
|
||||||
#define FPU_DOUBLE(var) double var; \
|
#define CREATE_FPU_FUNC1(name, call) \
|
||||||
__asm__ __volatile__( "fstpl %0;fwait" : "=m" (var) : )
|
__ASM_GLOBAL_FUNC(name, \
|
||||||
#define FPU_DOUBLES(var1,var2) double var1,var2; \
|
"pushl %ebp\n\t" \
|
||||||
__asm__ __volatile__( "fstpl %0;fwait" : "=m" (var2) : ); \
|
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
|
||||||
__asm__ __volatile__( "fstpl %0;fwait" : "=m" (var1) : )
|
__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) \
|
||||||
* _CIacos (MSVCRT.@)
|
__ASM_GLOBAL_FUNC(name, \
|
||||||
*/
|
"pushl %ebp\n\t" \
|
||||||
double CDECL _CIacos(void)
|
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") \
|
||||||
{
|
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t") \
|
||||||
FPU_DOUBLE(x);
|
"movl %esp, %ebp\n\t" \
|
||||||
return MSVCRT_acos(x);
|
__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)
|
||||||
* _CIasin (MSVCRT.@)
|
CREATE_FPU_FUNC1(_CIasin, MSVCRT_asin)
|
||||||
*/
|
CREATE_FPU_FUNC1(_CIatan, MSVCRT_atan)
|
||||||
double CDECL _CIasin(void)
|
CREATE_FPU_FUNC2(_CIatan2, MSVCRT_atan2)
|
||||||
{
|
CREATE_FPU_FUNC1(_CIcos, MSVCRT_cos)
|
||||||
FPU_DOUBLE(x);
|
CREATE_FPU_FUNC1(_CIcosh, MSVCRT_cosh)
|
||||||
return MSVCRT_asin(x);
|
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,
|
||||||
* _CIatan (MSVCRT.@)
|
"pushl %ebp\n\t"
|
||||||
*/
|
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||||
double CDECL _CIatan(void)
|
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
|
||||||
{
|
"movl %esp, %ebp\n\t"
|
||||||
FPU_DOUBLE(x);
|
__ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
|
||||||
return MSVCRT_atan(x);
|
"subl $12, %esp\n\t" /* sizeof(LONGLONG) + 2*sizeof(WORD) */
|
||||||
}
|
"fnstcw (%esp)\n\t"
|
||||||
|
"mov (%esp), %ax\n\t"
|
||||||
/*********************************************************************
|
"or $0xc, %ax\n\t"
|
||||||
* _CIatan2 (MSVCRT.@)
|
"mov %ax, 2(%esp)\n\t"
|
||||||
*/
|
"fldcw 2(%esp)\n\t"
|
||||||
double CDECL _CIatan2(void)
|
"fistpq 4(%esp)\n\t"
|
||||||
{
|
"fldcw (%esp)\n\t"
|
||||||
FPU_DOUBLES(x,y);
|
"movl 4(%esp), %eax\n\t"
|
||||||
return MSVCRT_atan2(x,y);
|
"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")
|
||||||
* _CIcos (MSVCRT.@)
|
"ret")
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* defined(__GNUC__) && defined(__i386__) */
|
#endif /* defined(__GNUC__) && defined(__i386__) */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue