mirror of
https://github.com/ptitSeb/box86.git
synced 2024-11-23 06:39:55 +00:00
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:
parent
35ea6fd109
commit
22ee4685a1
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) \
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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); \
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user