crt: Convert the arm sincos.c to assembly This avoids optimizing the sincos function to a recursive call to itself, if built with -ffast-math (unless built with -fno-builtin-sin). While building with -ffast-math can break certain math routines and thus can be considered a self-inflicted issue, it's safest to avoid constructs that potentially can be optimized into an infinite self recursion. Signed-off-by: Martin Storsjö <martin@martin.st>
diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am index 3feaa44..49cd701 100644 --- a/mingw-w64-crt/Makefile.am +++ b/mingw-w64-crt/Makefile.am
@@ -525,14 +525,15 @@ math/softmath/sinf.c math/softmath/sinl.c math/softmath/tanf.c math/softmath/tanl.c else src_libmingwexarm32+=\ - math/arm-common/ldexpl.c math/arm-common/sincos.c + math/arm-common/ldexpl.c math/arm/sincos.S math/arm/sincosf.S endif # these only go into the ARM64 version: src_libmingwexarm64=\ math/arm64/_chgsignl.S \ math/arm64/rint.c math/arm64/rintf.c \ - math/arm-common/ldexpl.c math/arm-common/sincos.c + math/arm64/sincos.S math/arm64/sincosf.S \ + math/arm-common/ldexpl.c # These intrinsics are target independent:
diff --git a/mingw-w64-crt/math/arm-common/sincos.c b/mingw-w64-crt/math/arm-common/sincos.c deleted file mode 100644 index 099351f..0000000 --- a/mingw-w64-crt/math/arm-common/sincos.c +++ /dev/null
@@ -1,29 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ - -#include <math.h> - -void sincos (double __x, double *p_sin, double *p_cos) -{ - *p_sin = sin(__x); - *p_cos = cos(__x); -} - -void sincosf (float __x, float *p_sin, float *p_cos) -{ - *p_sin = sinf(__x); - *p_cos = cosf(__x); -} - -void sincosl (long double __x, long double *p_sin, long double *p_cos) -{ -#if defined(__arm__) || defined(_ARM_) || defined(__aarch64__) || defined(_ARM64_) - *p_sin = sin(__x); - *p_cos = cos(__x); -#else -#error Not supported on your platform yet -#endif -}
diff --git a/mingw-w64-crt/math/arm/sincos.S b/mingw-w64-crt/math/arm/sincos.S new file mode 100644 index 0000000..2d3caa8 --- /dev/null +++ b/mingw-w64-crt/math/arm/sincos.S
@@ -0,0 +1,32 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ +#include <_mingw_mac.h> + + .file "sincos.S" + .text + .align 2 + .globl __MINGW_USYMBOL(sincos) + .globl __MINGW_USYMBOL(sincosl) + .def __MINGW_USYMBOL(sincos); .scl 2; .type 32; .endef + .def __MINGW_USYMBOL(sincosl); .scl 2; .type 32; .endef +__MINGW_USYMBOL(sincos): +__MINGW_USYMBOL(sincosl): + push {r4, r5, r11, lr} + add r11, sp, #8 + vpush {d8} + + mov r4, r0 + mov r5, r1 + vmov.f64 d8, d0 + bl sin + vstr d0, [r4] + + vmov.f64 d0, d8 + bl cos + vstr d0, [r5] + + vpop {d8} + pop {r4, r5, r11, pc}
diff --git a/mingw-w64-crt/math/arm/sincosf.S b/mingw-w64-crt/math/arm/sincosf.S new file mode 100644 index 0000000..ce88b18 --- /dev/null +++ b/mingw-w64-crt/math/arm/sincosf.S
@@ -0,0 +1,29 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ +#include <_mingw_mac.h> + + .file "sincosf.S" + .text + .align 2 + .globl __MINGW_USYMBOL(sincosf) + .def __MINGW_USYMBOL(sincosf); .scl 2; .type 32; .endef +__MINGW_USYMBOL(sincosf): + push {r4, r5, r11, lr} + add r11, sp, #8 + vpush {d8} + + mov r4, r0 + mov r5, r1 + vmov.f32 s16, s0 + bl sinf + vstr s0, [r4] + + vmov.f32 s0, s16 + bl cosf + vstr s0, [r5] + + vpop {d8} + pop {r4, r5, r11, pc}
diff --git a/mingw-w64-crt/math/arm64/sincos.S b/mingw-w64-crt/math/arm64/sincos.S new file mode 100644 index 0000000..f7ae446 --- /dev/null +++ b/mingw-w64-crt/math/arm64/sincos.S
@@ -0,0 +1,34 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ +#include <_mingw_mac.h> + + .file "sincos.S" + .text + .align 2 + .globl __MINGW_USYMBOL(sincos) + .globl __MINGW_USYMBOL(sincosl) + .def __MINGW_USYMBOL(sincos); .scl 2; .type 32; .endef + .def __MINGW_USYMBOL(sincosl); .scl 2; .type 32; .endef +__MINGW_USYMBOL(sincos): +__MINGW_USYMBOL(sincosl): + str d8, [sp, #-32]! + str x30, [sp, #8] + stp x19, x20, [sp, #16] + + mov x19, x0 + mov x20, x1 + fmov d8, d0 + bl sin + str d0, [x19] + + fmov d0, d8 + bl cos + str d0, [x20] + + ldp x19, x20, [sp, #16] + ldr x30, [sp, #8] + ldr d8, [sp], #32 + ret
diff --git a/mingw-w64-crt/math/arm64/sincosf.S b/mingw-w64-crt/math/arm64/sincosf.S new file mode 100644 index 0000000..6939eeb --- /dev/null +++ b/mingw-w64-crt/math/arm64/sincosf.S
@@ -0,0 +1,31 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ +#include <_mingw_mac.h> + + .file "sincosf.S" + .text + .align 2 + .globl __MINGW_USYMBOL(sincosf) + .def __MINGW_USYMBOL(sincosf); .scl 2; .type 32; .endef +__MINGW_USYMBOL(sincosf): + str d8, [sp, #-32]! + str x30, [sp, #8] + stp x19, x20, [sp, #16] + + mov x19, x0 + mov x20, x1 + fmov s8, s0 + bl sinf + str s0, [x19] + + fmov s0, s8 + bl cosf + str s0, [x20] + + ldp x19, x20, [sp, #16] + ldr x30, [sp, #8] + ldr d8, [sp], #32 + ret