Set rounding mode for some rounding functions of libm (#953)

This commit rewrites fesetround and fegetround to set and get the
rounding mode in x86emu, and applies the rounding mode on rounding
functions (`{,l,ll}rint{,f,l}` and `nearbyint{,f,l}`).
This commit is contained in:
Hagb (Junyu Guo 郭俊余) 2024-04-15 14:00:33 +08:00 committed by GitHub
parent 35ea6fd109
commit 22ee4685a1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 204 additions and 22 deletions

View File

@ -998,10 +998,10 @@ add_test(bswap ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref23.txt
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
#add_test(feround ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
# -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test24 -D TEST_OUTPUT=tmpfile24.txt
# -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref24.txt
# -P ${CMAKE_SOURCE_DIR}/runTest.cmake )
add_test(feround ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test24 -D TEST_OUTPUT=tmpfile24.txt
-D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref24.txt
-P ${CMAKE_SOURCE_DIR}/runTest.cmake )
add_test(sse4_2 ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX86}
-D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test25 -D TEST_OUTPUT=tmpfile25.txt

View File

@ -168,7 +168,10 @@
#() vFGG
#() cFpp
#() iFEv
#() iFEi
#() iFEu
#() iFEf
#() iFEd
#() iFEL
#() iFEp
#() iFwp
@ -203,6 +206,8 @@
#() iFpG
#() iFSi
#() iFGG
#() IFEf
#() IFEd
#() IFEp
#() IFII
#() IFpu
@ -236,6 +241,7 @@
#() UFUp
#() UFpp
#() UFss
#() fFEf
#() fFEp
#() fFif
#() fFfi
@ -243,6 +249,7 @@
#() fFfD
#() fFfp
#() fFpp
#() dFEd
#() dFid
#() dFuu
#() dFdi
@ -2391,7 +2398,6 @@
#defined(NOALIGN) iFipV
#defined(NOALIGN) iFiipV
#defined(NOALIGN) iFppiiiip
#!defined(NOALIGN) iFEi
#!defined(NOALIGN) iFEO
#!defined(NOALIGN) dFEp
#!defined(NOALIGN) iFEpI
@ -2406,6 +2412,9 @@
#defined(POWERPCLE) iFEiiiN
#!defined(POWERPCLE) iFiiiN
#defined(HAVE_LD80BITS) DFD
#defined(HAVE_LD80BITS) iFED
#defined(HAVE_LD80BITS) IFED
#defined(HAVE_LD80BITS) DFED
#defined(HAVE_LD80BITS) DFDD
#defined(HAVE_LD80BITS) DFDp
#defined(HAVE_LD80BITS) DFppi
@ -2413,6 +2422,8 @@
#defined(HAVE_LD80BITS) DFppip
#defined(HAVE_LD80BITS) iFDipppL
#defined(HAVE_LD80BITS) vFppippDDC
#!defined(HAVE_LD80BITS) iFK
#!defined(HAVE_LD80BITS) IFK
#!defined(HAVE_LD80BITS) KFK
#!defined(HAVE_LD80BITS) KFKK
#!defined(HAVE_LD80BITS) KFKp
@ -3437,6 +3448,26 @@ wrappedlibjpeg62:
- vFpipu:
- jpeg_write_marker
wrappedlibm:
- iFv:
- fegetround
- iFi:
- fesetround
- iFf:
- lrintf
- iFd:
- lrint
- iFD:
- lrintl
- iFK:
- lrintl
- IFf:
- llrintf
- IFd:
- llrint
- IFD:
- llrintl
- IFK:
- llrintl
- UFs:
- cacosf
- cacoshf
@ -3466,6 +3497,8 @@ wrappedlibm:
- __logf_finite
- __sinhf_finite
- __sqrtf_finite
- nearbyintf
- rintf
- dFd:
- __acos_finite
- __acosh_finite
@ -3478,8 +3511,12 @@ wrappedlibm:
- __log_finite
- __sinh_finite
- __sqrt_finite
- nearbyint
- rint
- DFD:
- nearbyintl
- pow10l
- rintl
- KFK:
- acoshl
- acosl
@ -3493,7 +3530,9 @@ wrappedlibm:
- ldexpl
- lgammal
- logl
- nearbyintl
- pow10l
- rintl
- tgammal
- fFff:
- __atan2f_finite

View File

@ -11,6 +11,16 @@
#define ADDED_FUNCTIONS()
#endif
typedef int32_t (*iFv_t)(void);
typedef int32_t (*iFi_t)(int32_t);
typedef int32_t (*iFf_t)(float);
typedef int32_t (*iFd_t)(double);
typedef int32_t (*iFD_t)(long double);
typedef int32_t (*iFK_t)(double);
typedef int64_t (*IFf_t)(float);
typedef int64_t (*IFd_t)(double);
typedef int64_t (*IFD_t)(long double);
typedef int64_t (*IFK_t)(double);
typedef uint64_t (*UFs_t)(void*);
typedef float (*fFf_t)(float);
typedef double (*dFd_t)(double);
@ -25,6 +35,16 @@ typedef uint64_t (*UFsvvs_t)(void*, void, void, void*);
typedef void* (*pFpsvvvvs_t)(void*, void*, void, void, void, void, void*);
#define SUPER() ADDED_FUNCTIONS() \
GO(fegetround, iFv_t) \
GO(fesetround, iFi_t) \
GO(lrintf, iFf_t) \
GO(lrint, iFd_t) \
GO(lrintl, iFD_t) \
GO(lrintl, iFK_t) \
GO(llrintf, IFf_t) \
GO(llrint, IFd_t) \
GO(llrintl, IFD_t) \
GO(llrintl, IFK_t) \
GO(cacosf, UFs_t) \
GO(cacoshf, UFs_t) \
GO(casinf, UFs_t) \
@ -52,6 +72,8 @@ typedef void* (*pFpsvvvvs_t)(void*, void*, void, void, void, void, void*);
GO(__logf_finite, fFf_t) \
GO(__sinhf_finite, fFf_t) \
GO(__sqrtf_finite, fFf_t) \
GO(nearbyintf, fFf_t) \
GO(rintf, fFf_t) \
GO(__acos_finite, dFd_t) \
GO(__acosh_finite, dFd_t) \
GO(__asin_finite, dFd_t) \
@ -63,7 +85,11 @@ typedef void* (*pFpsvvvvs_t)(void*, void*, void, void, void, void, void*);
GO(__log_finite, dFd_t) \
GO(__sinh_finite, dFd_t) \
GO(__sqrt_finite, dFd_t) \
GO(nearbyint, dFd_t) \
GO(rint, dFd_t) \
GO(nearbyintl, DFD_t) \
GO(pow10l, DFD_t) \
GO(rintl, DFD_t) \
GO(acoshl, KFK_t) \
GO(acosl, KFK_t) \
GO(asinhl, KFK_t) \
@ -76,7 +102,9 @@ typedef void* (*pFpsvvvvs_t)(void*, void*, void, void, void, void, void*);
GO(ldexpl, KFK_t) \
GO(lgammal, KFK_t) \
GO(logl, KFK_t) \
GO(nearbyintl, KFK_t) \
GO(pow10l, KFK_t) \
GO(rintl, KFK_t) \
GO(tgammal, KFK_t) \
GO(__atan2f_finite, fFff_t) \
GO(__hypotf_finite, fFff_t) \

View File

@ -240,7 +240,10 @@ typedef void (*vFGp_t)(void*, void*);
typedef void (*vFGG_t)(void*, void*);
typedef int8_t (*cFpp_t)(void*, void*);
typedef int32_t (*iFEv_t)(x86emu_t*);
typedef int32_t (*iFEi_t)(x86emu_t*, int32_t);
typedef int32_t (*iFEu_t)(x86emu_t*, uint32_t);
typedef int32_t (*iFEf_t)(x86emu_t*, float);
typedef int32_t (*iFEd_t)(x86emu_t*, double);
typedef int32_t (*iFEL_t)(x86emu_t*, uintptr_t);
typedef int32_t (*iFEp_t)(x86emu_t*, void*);
typedef int32_t (*iFwp_t)(int16_t, void*);
@ -275,6 +278,8 @@ typedef int32_t (*iFpP_t)(void*, void*);
typedef int32_t (*iFpG_t)(void*, void*);
typedef int32_t (*iFSi_t)(void*, int32_t);
typedef int32_t (*iFGG_t)(void*, void*);
typedef int64_t (*IFEf_t)(x86emu_t*, float);
typedef int64_t (*IFEd_t)(x86emu_t*, double);
typedef int64_t (*IFEp_t)(x86emu_t*, void*);
typedef int64_t (*IFII_t)(int64_t, int64_t);
typedef int64_t (*IFpu_t)(void*, uint32_t);
@ -308,6 +313,7 @@ typedef uint64_t (*UFUU_t)(uint64_t, uint64_t);
typedef uint64_t (*UFUp_t)(uint64_t, void*);
typedef uint64_t (*UFpp_t)(void*, void*);
typedef uint64_t (*UFss_t)(void*, void*);
typedef float (*fFEf_t)(x86emu_t*, float);
typedef float (*fFEp_t)(x86emu_t*, void*);
typedef float (*fFif_t)(int32_t, float);
typedef float (*fFfi_t)(float, int32_t);
@ -315,6 +321,7 @@ typedef float (*fFff_t)(float, float);
typedef float (*fFfD_t)(float, long double);
typedef float (*fFfp_t)(float, void*);
typedef float (*fFpp_t)(void*, void*);
typedef double (*dFEd_t)(x86emu_t*, double);
typedef double (*dFid_t)(int32_t, double);
typedef double (*dFuu_t)(uint32_t, uint32_t);
typedef double (*dFdi_t)(double, int32_t);
@ -2468,7 +2475,6 @@ typedef int32_t (*iFppiiiip_t)(void*, void*, int32_t, int32_t, int32_t, int32_t,
#endif
#if !defined(NOALIGN)
typedef int32_t (*iFEi_t)(x86emu_t*, int32_t);
typedef int32_t (*iFEO_t)(x86emu_t*, int32_t);
typedef double (*dFEp_t)(x86emu_t*, void*);
typedef int32_t (*iFEpI_t)(x86emu_t*, void*, int64_t);
@ -2492,6 +2498,9 @@ typedef int32_t (*iFiiiN_t)(int32_t, int32_t, int32_t, ...);
#if defined(HAVE_LD80BITS)
typedef long double (*DFD_t)(long double);
typedef int32_t (*iFED_t)(x86emu_t*, long double);
typedef int64_t (*IFED_t)(x86emu_t*, long double);
typedef long double (*DFED_t)(x86emu_t*, long double);
typedef long double (*DFDD_t)(long double, long double);
typedef long double (*DFDp_t)(long double, void*);
typedef long double (*DFppi_t)(void*, void*, int32_t);
@ -2502,6 +2511,8 @@ typedef void (*vFppippDDC_t)(void*, void*, int32_t, void*, void*, long double, l
#endif
#if !defined(HAVE_LD80BITS)
typedef int32_t (*iFK_t)(double);
typedef int64_t (*IFK_t)(double);
typedef double (*KFK_t)(double);
typedef double (*KFKK_t)(double, double);
typedef double (*KFKp_t)(double, void*);
@ -2683,7 +2694,10 @@ void vFGp(x86emu_t *emu, uintptr_t fcn) { vFGp_t fn = (vFGp_t)fcn; my_GValue_t a
void vFGG(x86emu_t *emu, uintptr_t fcn) { vFGG_t fn = (vFGG_t)fcn; my_GValue_t arg4; alignGValue(&arg4, *(void**)(R_ESP + 4)); my_GValue_t arg8; alignGValue(&arg8, *(void**)(R_ESP + 8)); fn(&arg4, &arg8); unalignGValue(*(void**)(R_ESP + 4), &arg4); unalignGValue(*(void**)(R_ESP + 8), &arg8); }
void cFpp(x86emu_t *emu, uintptr_t fcn) { cFpp_t fn = (cFpp_t)fcn; R_EAX=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8)); }
void iFEv(x86emu_t *emu, uintptr_t fcn) { iFEv_t fn = (iFEv_t)fcn; R_EAX=fn(emu); }
void iFEi(x86emu_t *emu, uintptr_t fcn) { iFEi_t fn = (iFEi_t)fcn; R_EAX=fn(emu, *(int32_t*)(R_ESP + 4)); }
void iFEu(x86emu_t *emu, uintptr_t fcn) { iFEu_t fn = (iFEu_t)fcn; R_EAX=fn(emu, *(uint32_t*)(R_ESP + 4)); }
void iFEf(x86emu_t *emu, uintptr_t fcn) { iFEf_t fn = (iFEf_t)fcn; R_EAX=fn(emu, *(float*)(R_ESP + 4)); }
void iFEd(x86emu_t *emu, uintptr_t fcn) { iFEd_t fn = (iFEd_t)fcn; R_EAX=fn(emu, *(double*)(R_ESP + 4)); }
void iFEL(x86emu_t *emu, uintptr_t fcn) { iFEL_t fn = (iFEL_t)fcn; R_EAX=fn(emu, *(uintptr_t*)(R_ESP + 4)); }
void iFEp(x86emu_t *emu, uintptr_t fcn) { iFEp_t fn = (iFEp_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4)); }
void iFwp(x86emu_t *emu, uintptr_t fcn) { iFwp_t fn = (iFwp_t)fcn; R_EAX=fn(*(int16_t*)(R_ESP + 4), *(void**)(R_ESP + 8)); }
@ -2718,6 +2732,8 @@ void iFpP(x86emu_t *emu, uintptr_t fcn) { iFpP_t fn = (iFpP_t)fcn; void *arg8 =
void iFpG(x86emu_t *emu, uintptr_t fcn) { iFpG_t fn = (iFpG_t)fcn; my_GValue_t arg8; alignGValue(&arg8, *(void**)(R_ESP + 8)); R_EAX=fn(*(void**)(R_ESP + 4), &arg8); unalignGValue(*(void**)(R_ESP + 8), &arg8); }
void iFSi(x86emu_t *emu, uintptr_t fcn) { iFSi_t fn = (iFSi_t)fcn; R_EAX=fn(io_convert(*(void**)(R_ESP + 4)), *(int32_t*)(R_ESP + 8)); }
void iFGG(x86emu_t *emu, uintptr_t fcn) { iFGG_t fn = (iFGG_t)fcn; my_GValue_t arg4; alignGValue(&arg4, *(void**)(R_ESP + 4)); my_GValue_t arg8; alignGValue(&arg8, *(void**)(R_ESP + 8)); R_EAX=fn(&arg4, &arg8); unalignGValue(*(void**)(R_ESP + 4), &arg4); unalignGValue(*(void**)(R_ESP + 8), &arg8); }
void IFEf(x86emu_t *emu, uintptr_t fcn) { IFEf_t fn = (IFEf_t)fcn; ui64_t r; r.i=fn(emu, *(float*)(R_ESP + 4)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
void IFEd(x86emu_t *emu, uintptr_t fcn) { IFEd_t fn = (IFEd_t)fcn; ui64_t r; r.i=fn(emu, *(double*)(R_ESP + 4)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
void IFEp(x86emu_t *emu, uintptr_t fcn) { IFEp_t fn = (IFEp_t)fcn; ui64_t r; r.i=fn(emu, *(void**)(R_ESP + 4)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
void IFII(x86emu_t *emu, uintptr_t fcn) { IFII_t fn = (IFII_t)fcn; ui64_t r; r.i=fn(*(int64_t*)(R_ESP + 4), *(int64_t*)(R_ESP + 12)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
void IFpu(x86emu_t *emu, uintptr_t fcn) { IFpu_t fn = (IFpu_t)fcn; ui64_t r; r.i=fn(*(void**)(R_ESP + 4), *(uint32_t*)(R_ESP + 8)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
@ -2751,6 +2767,7 @@ void UFUU(x86emu_t *emu, uintptr_t fcn) { UFUU_t fn = (UFUU_t)fcn; ui64_t r; r.u
void UFUp(x86emu_t *emu, uintptr_t fcn) { UFUp_t fn = (UFUp_t)fcn; ui64_t r; r.u=(uint64_t)fn(*(uint64_t*)(R_ESP + 4), *(void**)(R_ESP + 12)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
void UFpp(x86emu_t *emu, uintptr_t fcn) { UFpp_t fn = (UFpp_t)fcn; ui64_t r; r.u=(uint64_t)fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
void UFss(x86emu_t *emu, uintptr_t fcn) { UFss_t fn = (UFss_t)fcn; ui64_t r; r.u=(uint64_t)fn((void*)(R_ESP + 4), (void*)(R_ESP + 4)); R_EAX=r.d[0]; R_EDX=r.d[1]; }
void fFEf(x86emu_t *emu, uintptr_t fcn) { fFEf_t fn = (fFEf_t)fcn; float fl=fn(emu, *(float*)(R_ESP + 4)); fpu_do_push(emu); ST0val = fl; }
void fFEp(x86emu_t *emu, uintptr_t fcn) { fFEp_t fn = (fFEp_t)fcn; float fl=fn(emu, *(void**)(R_ESP + 4)); fpu_do_push(emu); ST0val = fl; }
void fFif(x86emu_t *emu, uintptr_t fcn) { fFif_t fn = (fFif_t)fcn; float fl=fn(*(int32_t*)(R_ESP + 4), *(float*)(R_ESP + 8)); fpu_do_push(emu); ST0val = fl; }
void fFfi(x86emu_t *emu, uintptr_t fcn) { fFfi_t fn = (fFfi_t)fcn; float fl=fn(*(float*)(R_ESP + 4), *(int32_t*)(R_ESP + 8)); fpu_do_push(emu); ST0val = fl; }
@ -2758,6 +2775,7 @@ void fFff(x86emu_t *emu, uintptr_t fcn) { fFff_t fn = (fFff_t)fcn; float fl=fn(*
void fFfD(x86emu_t *emu, uintptr_t fcn) { fFfD_t fn = (fFfD_t)fcn; float fl=fn(*(float*)(R_ESP + 4), LD2localLD((void*)(R_ESP + 8))); fpu_do_push(emu); ST0val = fl; }
void fFfp(x86emu_t *emu, uintptr_t fcn) { fFfp_t fn = (fFfp_t)fcn; float fl=fn(*(float*)(R_ESP + 4), *(void**)(R_ESP + 8)); fpu_do_push(emu); ST0val = fl; }
void fFpp(x86emu_t *emu, uintptr_t fcn) { fFpp_t fn = (fFpp_t)fcn; float fl=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8)); fpu_do_push(emu); ST0val = fl; }
void dFEd(x86emu_t *emu, uintptr_t fcn) { dFEd_t fn = (dFEd_t)fcn; double db=fn(emu, *(double*)(R_ESP + 4)); fpu_do_push(emu); ST0val = db; }
void dFid(x86emu_t *emu, uintptr_t fcn) { dFid_t fn = (dFid_t)fcn; double db=fn(*(int32_t*)(R_ESP + 4), *(double*)(R_ESP + 8)); fpu_do_push(emu); ST0val = db; }
void dFuu(x86emu_t *emu, uintptr_t fcn) { dFuu_t fn = (dFuu_t)fcn; double db=fn(*(uint32_t*)(R_ESP + 4), *(uint32_t*)(R_ESP + 8)); fpu_do_push(emu); ST0val = db; }
void dFdi(x86emu_t *emu, uintptr_t fcn) { dFdi_t fn = (dFdi_t)fcn; double db=fn(*(double*)(R_ESP + 4), *(int32_t*)(R_ESP + 12)); fpu_do_push(emu); ST0val = db; }
@ -4911,7 +4929,6 @@ void iFppiiiip(x86emu_t *emu, uintptr_t fcn) { iFppiiiip_t fn = (iFppiiiip_t)fcn
#endif
#if !defined(NOALIGN)
void iFEi(x86emu_t *emu, uintptr_t fcn) { iFEi_t fn = (iFEi_t)fcn; R_EAX=fn(emu, *(int32_t*)(R_ESP + 4)); }
void iFEO(x86emu_t *emu, uintptr_t fcn) { iFEO_t fn = (iFEO_t)fcn; R_EAX=fn(emu, of_convert(*(int32_t*)(R_ESP + 4))); }
void dFEp(x86emu_t *emu, uintptr_t fcn) { dFEp_t fn = (dFEp_t)fcn; double db=fn(emu, *(void**)(R_ESP + 4)); fpu_do_push(emu); ST0val = db; }
void iFEpI(x86emu_t *emu, uintptr_t fcn) { iFEpI_t fn = (iFEpI_t)fcn; R_EAX=fn(emu, *(void**)(R_ESP + 4), *(int64_t*)(R_ESP + 8)); }
@ -4935,6 +4952,9 @@ void iFiiiN(x86emu_t *emu, uintptr_t fcn) { iFiiiN_t fn = (iFiiiN_t)fcn; R_EAX=f
#if defined(HAVE_LD80BITS)
void DFD(x86emu_t *emu, uintptr_t fcn) { DFD_t fn = (DFD_t)fcn; long double ld=fn(LD2localLD((void*)(R_ESP + 4))); fpu_do_push(emu); ST0val = ld; }
void iFED(x86emu_t *emu, uintptr_t fcn) { iFED_t fn = (iFED_t)fcn; R_EAX=fn(emu, LD2localLD((void*)(R_ESP + 4))); }
void IFED(x86emu_t *emu, uintptr_t fcn) { IFED_t fn = (IFED_t)fcn; ui64_t r; r.i=fn(emu, LD2localLD((void*)(R_ESP + 4))); R_EAX=r.d[0]; R_EDX=r.d[1]; }
void DFED(x86emu_t *emu, uintptr_t fcn) { DFED_t fn = (DFED_t)fcn; long double ld=fn(emu, LD2localLD((void*)(R_ESP + 4))); fpu_do_push(emu); ST0val = ld; }
void DFDD(x86emu_t *emu, uintptr_t fcn) { DFDD_t fn = (DFDD_t)fcn; long double ld=fn(LD2localLD((void*)(R_ESP + 4)), LD2localLD((void*)(R_ESP + 16))); fpu_do_push(emu); ST0val = ld; }
void DFDp(x86emu_t *emu, uintptr_t fcn) { DFDp_t fn = (DFDp_t)fcn; long double ld=fn(LD2localLD((void*)(R_ESP + 4)), *(void**)(R_ESP + 16)); fpu_do_push(emu); ST0val = ld; }
void DFppi(x86emu_t *emu, uintptr_t fcn) { DFppi_t fn = (DFppi_t)fcn; long double ld=fn(*(void**)(R_ESP + 4), *(void**)(R_ESP + 8), *(int32_t*)(R_ESP + 12)); fpu_do_push(emu); ST0val = ld; }
@ -4945,6 +4965,8 @@ void vFppippDDC(x86emu_t *emu, uintptr_t fcn) { vFppippDDC_t fn = (vFppippDDC_t)
#endif
#if !defined(HAVE_LD80BITS)
void iFK(x86emu_t *emu, uintptr_t fcn) { iFK_t fn = (iFK_t)fcn; R_EAX=fn(FromLD((void*)(R_ESP + 4))); }
void IFK(x86emu_t *emu, uintptr_t fcn) { IFK_t fn = (IFK_t)fcn; ui64_t r; r.i=fn(FromLD((void*)(R_ESP + 4))); R_EAX=r.d[0]; R_EDX=r.d[1]; }
void KFK(x86emu_t *emu, uintptr_t fcn) { KFK_t fn = (KFK_t)fcn; double db=fn(FromLD((void*)(R_ESP + 4))); fpu_do_push(emu); ST0val = db; }
void KFKK(x86emu_t *emu, uintptr_t fcn) { KFKK_t fn = (KFKK_t)fcn; double db=fn(FromLD((void*)(R_ESP + 4)), FromLD((void*)(R_ESP + 16))); fpu_do_push(emu); ST0val = db; }
void KFKp(x86emu_t *emu, uintptr_t fcn) { KFKp_t fn = (KFKp_t)fcn; double db=fn(FromLD((void*)(R_ESP + 4)), *(void**)(R_ESP + 16)); fpu_do_push(emu); ST0val = db; }
@ -4982,6 +5004,7 @@ int isRetX87Wrapper(wrapper_t fun) {
if (fun == &dFd) return 1;
if (fun == &dFp) return 1;
if (fun == &dFG) return 1;
if (fun == &fFEf) return 1;
if (fun == &fFEp) return 1;
if (fun == &fFif) return 1;
if (fun == &fFfi) return 1;
@ -4989,6 +5012,7 @@ int isRetX87Wrapper(wrapper_t fun) {
if (fun == &fFfD) return 1;
if (fun == &fFfp) return 1;
if (fun == &fFpp) return 1;
if (fun == &dFEd) return 1;
if (fun == &dFid) return 1;
if (fun == &dFuu) return 1;
if (fun == &dFdi) return 1;
@ -5017,6 +5041,7 @@ int isRetX87Wrapper(wrapper_t fun) {
#endif
#if defined(HAVE_LD80BITS)
if (fun == &DFD) return 1;
if (fun == &DFED) return 1;
if (fun == &DFDD) return 1;
if (fun == &DFDp) return 1;
if (fun == &DFppi) return 1;

View File

@ -200,7 +200,10 @@ void vFGp(x86emu_t *emu, uintptr_t fnc);
void vFGG(x86emu_t *emu, uintptr_t fnc);
void cFpp(x86emu_t *emu, uintptr_t fnc);
void iFEv(x86emu_t *emu, uintptr_t fnc);
void iFEi(x86emu_t *emu, uintptr_t fnc);
void iFEu(x86emu_t *emu, uintptr_t fnc);
void iFEf(x86emu_t *emu, uintptr_t fnc);
void iFEd(x86emu_t *emu, uintptr_t fnc);
void iFEL(x86emu_t *emu, uintptr_t fnc);
void iFEp(x86emu_t *emu, uintptr_t fnc);
void iFwp(x86emu_t *emu, uintptr_t fnc);
@ -235,6 +238,8 @@ void iFpP(x86emu_t *emu, uintptr_t fnc);
void iFpG(x86emu_t *emu, uintptr_t fnc);
void iFSi(x86emu_t *emu, uintptr_t fnc);
void iFGG(x86emu_t *emu, uintptr_t fnc);
void IFEf(x86emu_t *emu, uintptr_t fnc);
void IFEd(x86emu_t *emu, uintptr_t fnc);
void IFEp(x86emu_t *emu, uintptr_t fnc);
void IFII(x86emu_t *emu, uintptr_t fnc);
void IFpu(x86emu_t *emu, uintptr_t fnc);
@ -268,6 +273,7 @@ void UFUU(x86emu_t *emu, uintptr_t fnc);
void UFUp(x86emu_t *emu, uintptr_t fnc);
void UFpp(x86emu_t *emu, uintptr_t fnc);
void UFss(x86emu_t *emu, uintptr_t fnc);
void fFEf(x86emu_t *emu, uintptr_t fnc);
void fFEp(x86emu_t *emu, uintptr_t fnc);
void fFif(x86emu_t *emu, uintptr_t fnc);
void fFfi(x86emu_t *emu, uintptr_t fnc);
@ -275,6 +281,7 @@ void fFff(x86emu_t *emu, uintptr_t fnc);
void fFfD(x86emu_t *emu, uintptr_t fnc);
void fFfp(x86emu_t *emu, uintptr_t fnc);
void fFpp(x86emu_t *emu, uintptr_t fnc);
void dFEd(x86emu_t *emu, uintptr_t fnc);
void dFid(x86emu_t *emu, uintptr_t fnc);
void dFuu(x86emu_t *emu, uintptr_t fnc);
void dFdi(x86emu_t *emu, uintptr_t fnc);
@ -2428,7 +2435,6 @@ void iFppiiiip(x86emu_t *emu, uintptr_t fnc);
#endif
#if !defined(NOALIGN)
void iFEi(x86emu_t *emu, uintptr_t fnc);
void iFEO(x86emu_t *emu, uintptr_t fnc);
void dFEp(x86emu_t *emu, uintptr_t fnc);
void iFEpI(x86emu_t *emu, uintptr_t fnc);
@ -2452,6 +2458,9 @@ void iFiiiN(x86emu_t *emu, uintptr_t fnc);
#if defined(HAVE_LD80BITS)
void DFD(x86emu_t *emu, uintptr_t fnc);
void iFED(x86emu_t *emu, uintptr_t fnc);
void IFED(x86emu_t *emu, uintptr_t fnc);
void DFED(x86emu_t *emu, uintptr_t fnc);
void DFDD(x86emu_t *emu, uintptr_t fnc);
void DFDp(x86emu_t *emu, uintptr_t fnc);
void DFppi(x86emu_t *emu, uintptr_t fnc);
@ -2462,6 +2471,8 @@ void vFppippDDC(x86emu_t *emu, uintptr_t fnc);
#endif
#if !defined(HAVE_LD80BITS)
void iFK(x86emu_t *emu, uintptr_t fnc);
void IFK(x86emu_t *emu, uintptr_t fnc);
void KFK(x86emu_t *emu, uintptr_t fnc);
void KFKK(x86emu_t *emu, uintptr_t fnc);
void KFKp(x86emu_t *emu, uintptr_t fnc);

View File

@ -12,6 +12,8 @@
#include "bridge.h"
#include "librarian/library_private.h"
#include "x86emu.h"
#include "emu/x86emu_private.h"
#include "emu/x87emu_setround.h"
#include "debug.h"
const char* libmName =
@ -25,6 +27,18 @@ const char* libmName =
static library_t* my_lib = NULL;
EXPORT int my_fesetround (x86emu_t* emu, int __rounding_direction) {
if ((~0xc00 & (unsigned int)__rounding_direction) != 0) // invalid rounding
return 1;
emu->cw.f.C87_RD = __rounding_direction >> 10;
return 0;
}
EXPORT int my_fegetround (x86emu_t* emu) {
return emu->cw.f.C87_RD << 10;
}
typedef float (*fFff_t) (float, float);
typedef double (*dFdd_t) (double, double);
typedef float (*fFf_t) (float);
@ -35,6 +49,11 @@ typedef union my_float_complex_s {
uint64_t u64;
} my_float_complex_t;
#define set_round() \
int oldround = fpu_setround(emu)
#define restore_round() \
fesetround(oldround)
// complex <- FUNC(complex) wrapper
#define GO_cFc(N) \
EXPORT void* my_##N(void* p, void* c) \
@ -145,6 +164,50 @@ F1D(log)
#undef F1F
#undef FINITE
#define WITH_ROUND(N, R, P, ...) \
EXPORT R my_##N P \
{ \
set_round(); \
R ret = N(__VA_ARGS__); \
restore_round(); \
return ret; \
}
#ifdef HAVE_LD80BITS
#define RFr(N, r) \
WITH_ROUND(N ## f, r, (x86emu_t* emu, float a), a) \
WITH_ROUND(N, r, (x86emu_t* emu, double a), a) \
WITH_ROUND(N ## l, r, (x86emu_t* emu, long double a), a)
#define RrFr(N) \
WITH_ROUND(N ## f, float, (x86emu_t* emu, float a), a) \
WITH_ROUND(N, double, (x86emu_t* emu, double a), a) \
WITH_ROUND(N ## l, double, (x86emu_t* emu, long double a), a)
#define RrFrr(N) \
WITH_ROUND(N ## f, float, (x86emu_t* emu, float a, float b), a, b) \
WITH_ROUND(N, double, (x86emu_t* emu, double a, double b), a, b) \
WITH_ROUND(N ## l, double, (x86emu_t* emu, long double a, long double b), a, b)
#else
#define RFr(N, r) \
WITH_ROUND(N ## f, r, (x86emu_t* emu, float a), a) \
WITH_ROUND(N, r, (x86emu_t* emu, double a), a)
#define RrFr(N) \
WITH_ROUND(N ## f, float, (x86emu_t* emu, float a), a) \
WITH_ROUND(N, double, (x86emu_t* emu, double a), a)
#define RrFrr(N) \
WITH_ROUND(N ## f, float, (x86emu_t* emu, float a, float b), a, b) \
WITH_ROUND(N, double, (x86emu_t* emu, double a, double b), a, b)
#endif
RrFr(nearbyint)
RrFr(rint)
RFr(llrint, long long)
RFr(lrint, int)
#undef RFr
#undef RrFr
#undef RrFrr
#undef WITH_ROUND
#define PRE_INIT\
if(1) \
lib->w.lib = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL); \

View File

@ -196,12 +196,12 @@ GO(feenableexcept, iFi)
GO(fegetenv, iFp)
GO(fegetexcept, iFv)
GO(fegetexceptflag, iFpi)
GO(fegetround, iFv)
GOM(fegetround, iFEv)
GO(feholdexcept, iFp)
GO(feraiseexcept, iFi)
GO(fesetenv, iFp)
GO(fesetexceptflag, iFpi)
GO(fesetround, iFi)
GOM(fesetround, iFEi)
GO(fetestexcept, iFi)
GO(feupdateenv, iFp)
GOW(finite, iFd)
@ -301,9 +301,13 @@ GOW2(lgammal_r, KFKp, lgamma_r)
GOW(lgamma_r, dFdp)
// __lgamma_r_finite
DATAV(_LIB_VERSION, 4)
GOW(llrint, IFd)
GOW(llrintf, IFf)
// llrintl // Weak
GOM(llrint, IFEd)
GOM(llrintf, IFEf)
#ifdef HAVE_LD80BITS
GOM(llrintl, IFED)
#else
GO2(llrintl, IFK, llrint)
#endif
GOW(llround, IFd)
GOW(llroundf, IFf)
// llroundl // Weak
@ -332,9 +336,13 @@ GOW(logl, DFD)
#else
GOW2(logl, KFK, log)
#endif
GOW(lrint, iFd)
GOW(lrintf, iFf)
// lrintl // Weak
GOM(lrint, iFEd)
GOM(lrintf, iFEf)
#ifdef HAVE_LD80BITS
GOM(lrintl, iFED)
#else
GO2(lrintl, iFK, lrint)
#endif
GOW(lround, iFd)
GOW(lroundf, iFf)
// lroundl // Weak
@ -345,9 +353,13 @@ GOW(modff, fFfp)
// nan // Weak
// nanf // Weak
// nanl // Weak
GOW(nearbyint, dFd)
GOW(nearbyintf, fFf)
// nearbyintl // Weak
GOM(nearbyint, dFEd)
GOM(nearbyintf, fFEf)
#ifdef HAVE_LD80BITS
GOM(nearbyintl, DFED)
#else
GO2(nearbyintl, KFK, nearbyint)
#endif
GOW(nextafter, dFdd)
GOW(nextafterf, fFff)
// nextafterl // Weak
@ -378,9 +390,13 @@ GOW(remainderf, fFff)
GOW(remquo, dFddp)
GOW(remquof, fFffp)
// remquol // Weak
GOW(rint, dFd)
GOW(rintf, fFf)
// rintl // Weak
GOM(rint, dFEd)
GOM(rintf, fFEf)
#ifdef HAVE_LD80BITS
GOM(rintl, DFED)
#else
GO2(rintl, KFK, rint)
#endif
GOW(round, dFd)
GOW(roundf, fFf)
// roundl // Weak