All of these has been tested for at least a few different types of inputs. The assembly functions have been tested with NAN and INF.
Signed-off-by: Martin Storsjö <mar...@martin.st> --- mingw-w64-crt/Makefile.am | 6 +++++- mingw-w64-crt/math/arm64/_chgsignl.S | 16 ++++++++++++++++ mingw-w64-crt/math/arm64/ceil.S | 16 ++++++++++++++++ mingw-w64-crt/math/arm64/ceilf.S | 16 ++++++++++++++++ mingw-w64-crt/math/arm64/ceill.S | 15 +++++++++++++++ mingw-w64-crt/math/arm64/copysignl.c | 11 +++++++++++ mingw-w64-crt/math/arm64/exp2.c | 26 ++++++++++++++++++++++++++ mingw-w64-crt/math/arm64/floor.S | 15 +++++++++++++++ mingw-w64-crt/math/arm64/floorf.S | 15 +++++++++++++++ mingw-w64-crt/math/arm64/floorl.S | 15 +++++++++++++++ mingw-w64-crt/math/arm64/log2.c | 26 ++++++++++++++++++++++++++ mingw-w64-crt/math/arm64/nearbyint.S | 17 +++++++++++++++++ mingw-w64-crt/math/arm64/nearbyintf.S | 17 +++++++++++++++++ mingw-w64-crt/math/arm64/nearbyintl.S | 17 +++++++++++++++++ mingw-w64-crt/math/arm64/scalbn.c | 26 ++++++++++++++++++++++++++ mingw-w64-crt/math/arm64/sincos.c | 29 +++++++++++++++++++++++++++++ mingw-w64-crt/math/arm64/trunc.S | 16 ++++++++++++++++ mingw-w64-crt/math/arm64/truncf.S | 16 ++++++++++++++++ mingw-w64-crt/math/fma.c | 12 ++++++++++++ mingw-w64-crt/math/fmaf.c | 12 ++++++++++++ mingw-w64-crt/math/lrint.c | 5 +++++ mingw-w64-crt/math/lrintf.c | 5 +++++ mingw-w64-crt/math/rint.c | 2 ++ mingw-w64-crt/math/rintf.c | 2 ++ mingw-w64-crt/math/sqrt.def.h | 6 ++++++ 25 files changed, 358 insertions(+), 1 deletion(-) create mode 100644 mingw-w64-crt/math/arm64/_chgsignl.S create mode 100644 mingw-w64-crt/math/arm64/ceil.S create mode 100644 mingw-w64-crt/math/arm64/ceilf.S create mode 100644 mingw-w64-crt/math/arm64/ceill.S create mode 100644 mingw-w64-crt/math/arm64/copysignl.c create mode 100644 mingw-w64-crt/math/arm64/exp2.c create mode 100644 mingw-w64-crt/math/arm64/floor.S create mode 100644 mingw-w64-crt/math/arm64/floorf.S create mode 100644 mingw-w64-crt/math/arm64/floorl.S create mode 100644 mingw-w64-crt/math/arm64/log2.c create mode 100644 mingw-w64-crt/math/arm64/nearbyint.S create mode 100644 mingw-w64-crt/math/arm64/nearbyintf.S create mode 100644 mingw-w64-crt/math/arm64/nearbyintl.S create mode 100644 mingw-w64-crt/math/arm64/scalbn.c create mode 100644 mingw-w64-crt/math/arm64/sincos.c create mode 100644 mingw-w64-crt/math/arm64/trunc.S create mode 100644 mingw-w64-crt/math/arm64/truncf.S diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am index 49778b0..4c1cf66 100644 --- a/mingw-w64-crt/Makefile.am +++ b/mingw-w64-crt/Makefile.am @@ -353,7 +353,11 @@ src_libmingwexarm32+=\ endif # these only go into the ARM64 version: -src_libmingwexarm64= +src_libmingwexarm64=\ + math/arm64/_chgsignl.S math/arm64/ceil.S math/arm64/ceilf.S math/arm64/ceill.S math/arm64/copysignl.c \ + math/arm64/exp2.c math/arm64/floor.S math/arm64/floorf.S math/arm64/floorl.S math/arm64/log2.c \ + math/arm64/nearbyint.S math/arm64/nearbyintf.S math/arm64/nearbyintl.S math/arm64/scalbn.c math/arm64/sincos.c \ + math/arm64/trunc.S math/arm64/truncf.S # These intrinsics are target independent: diff --git a/mingw-w64-crt/math/arm64/_chgsignl.S b/mingw-w64-crt/math/arm64/_chgsignl.S new file mode 100644 index 0000000..0472c70 --- /dev/null +++ b/mingw-w64-crt/math/arm64/_chgsignl.S @@ -0,0 +1,16 @@ +/** + * 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 "_chgignl.S" + .text + .align 2 + .globl __MINGW_USYMBOL(_chgsignl) + .def __MINGW_USYMBOL(_chgsignl); .scl 2; .type 32; .endef +__MINGW_USYMBOL(_chgsignl): + fneg d0, d0 + ret diff --git a/mingw-w64-crt/math/arm64/ceil.S b/mingw-w64-crt/math/arm64/ceil.S new file mode 100644 index 0000000..6f46d35 --- /dev/null +++ b/mingw-w64-crt/math/arm64/ceil.S @@ -0,0 +1,16 @@ +/** + * 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 "ceil.S" + .text + .align 2 + .globl __MINGW_USYMBOL(ceil) + .def __MINGW_USYMBOL(ceil); .scl 2; .type 32; .endef + +__MINGW_USYMBOL(ceil): + frintp d0, d0 + ret diff --git a/mingw-w64-crt/math/arm64/ceilf.S b/mingw-w64-crt/math/arm64/ceilf.S new file mode 100644 index 0000000..b67d768 --- /dev/null +++ b/mingw-w64-crt/math/arm64/ceilf.S @@ -0,0 +1,16 @@ +/** + * 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 "ceilf.S" + .text + .align 2 + .globl __MINGW_USYMBOL(ceilf) + .def __MINGW_USYMBOL(ceilf); .scl 2; .type 32; .endef + +__MINGW_USYMBOL(ceilf): + frintp s0, s0 + ret diff --git a/mingw-w64-crt/math/arm64/ceill.S b/mingw-w64-crt/math/arm64/ceill.S new file mode 100644 index 0000000..99385a3 --- /dev/null +++ b/mingw-w64-crt/math/arm64/ceill.S @@ -0,0 +1,15 @@ +/** + * 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 "ceill.S" + .text + .align 2 + .globl __MINGW_USYMBOL(ceill) + .def __MINGW_USYMBOL(ceill); .scl 2; .type 32; .endef +__MINGW_USYMBOL(ceill): + frintp d0, d0 + ret diff --git a/mingw-w64-crt/math/arm64/copysignl.c b/mingw-w64-crt/math/arm64/copysignl.c new file mode 100644 index 0000000..ea66215 --- /dev/null +++ b/mingw-w64-crt/math/arm64/copysignl.c @@ -0,0 +1,11 @@ +/** + * 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> + +long double copysignl(long double x, long double y) +{ + return copysign(x, y); +} diff --git a/mingw-w64-crt/math/arm64/exp2.c b/mingw-w64-crt/math/arm64/exp2.c new file mode 100644 index 0000000..eb9ddf5 --- /dev/null +++ b/mingw-w64-crt/math/arm64/exp2.c @@ -0,0 +1,26 @@ +/** + * 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> + +double exp2(double x) +{ + return pow(2, x); +} + +float exp2f(float x) +{ + return powf(2, x); +} + +long double exp2l(long double x) +{ +#if defined(__aarch64__) || defined(_ARM64_) + return exp2(x); +#else +#error Not supported on your platform yet +#endif +} diff --git a/mingw-w64-crt/math/arm64/floor.S b/mingw-w64-crt/math/arm64/floor.S new file mode 100644 index 0000000..fc3f002 --- /dev/null +++ b/mingw-w64-crt/math/arm64/floor.S @@ -0,0 +1,15 @@ +/** + * 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 "floor.S" + .text + .p2align 2 + .globl __MINGW_USYMBOL(floor) + .def __MINGW_USYMBOL(floor); .scl 2; .type 32; .endef +__MINGW_USYMBOL(floor): + frintm d0, d0 + ret diff --git a/mingw-w64-crt/math/arm64/floorf.S b/mingw-w64-crt/math/arm64/floorf.S new file mode 100644 index 0000000..d24db92 --- /dev/null +++ b/mingw-w64-crt/math/arm64/floorf.S @@ -0,0 +1,15 @@ +/** + * 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 "floorf.S" + .text + .p2align 2 + .globl __MINGW_USYMBOL(floorf) + .def __MINGW_USYMBOL(floorf); .scl 2; .type 32; .endef +__MINGW_USYMBOL(floorf): + frintm s0, s0 + ret diff --git a/mingw-w64-crt/math/arm64/floorl.S b/mingw-w64-crt/math/arm64/floorl.S new file mode 100644 index 0000000..746738d --- /dev/null +++ b/mingw-w64-crt/math/arm64/floorl.S @@ -0,0 +1,15 @@ +/** + * 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 "floorl.S" + .text + .align 2 + .globl __MINGW_USYMBOL(floorl) + .def __MINGW_USYMBOL(floorl); .scl 2; .type 32; .endef +__MINGW_USYMBOL(floorl): + frintm d0, d0 + ret diff --git a/mingw-w64-crt/math/arm64/log2.c b/mingw-w64-crt/math/arm64/log2.c new file mode 100644 index 0000000..6196f42 --- /dev/null +++ b/mingw-w64-crt/math/arm64/log2.c @@ -0,0 +1,26 @@ +/** + * 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> + +double log2(double x) +{ + return log(x) / 0.69314718246459960938; +} + +float log2f(float x) +{ + return logf(x) / 0.69314718246459960938f; +} + +long double log2l(long double x) +{ +#if defined(__aarch64__) || defined(_ARM64_) + return log2(x); +#else +#error Not supported on your platform yet +#endif +} diff --git a/mingw-w64-crt/math/arm64/nearbyint.S b/mingw-w64-crt/math/arm64/nearbyint.S new file mode 100644 index 0000000..b17ce2b --- /dev/null +++ b/mingw-w64-crt/math/arm64/nearbyint.S @@ -0,0 +1,17 @@ +/** + * 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 "nearbyint.S" + .text + .align 2 + .globl __MINGW_USYMBOL(nearbyint) + .def __MINGW_USYMBOL(nearbyint); .scl 2; .type 32; .endef +__MINGW_USYMBOL(nearbyint): + mrs x1, fpcr + frintx d0, d0 + msr fpcr, x1 + ret diff --git a/mingw-w64-crt/math/arm64/nearbyintf.S b/mingw-w64-crt/math/arm64/nearbyintf.S new file mode 100644 index 0000000..49b6aff --- /dev/null +++ b/mingw-w64-crt/math/arm64/nearbyintf.S @@ -0,0 +1,17 @@ +/** + * 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 "nearbyintf.S" + .text + .align 2 + .globl __MINGW_USYMBOL(nearbyintf) + .def __MINGW_USYMBOL(nearbyintf); .scl 2; .type 32; .endef +__MINGW_USYMBOL(nearbyintf): + mrs x1, fpcr + frintx s0, s0 + msr fpcr, x1 + ret diff --git a/mingw-w64-crt/math/arm64/nearbyintl.S b/mingw-w64-crt/math/arm64/nearbyintl.S new file mode 100644 index 0000000..cbfebb2 --- /dev/null +++ b/mingw-w64-crt/math/arm64/nearbyintl.S @@ -0,0 +1,17 @@ +/** + * 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 "nearbyintl.S" + .text + .align 2 + .globl __MINGW_USYMBOL(nearbyintl) + .def __MINGW_USYMBOL(nearbyintl); .scl 2; .type 32; .endef +__MINGW_USYMBOL(nearbyintl): + mrs x1, fpcr + frintx d0, d0 + msr fpcr, x1 + ret diff --git a/mingw-w64-crt/math/arm64/scalbn.c b/mingw-w64-crt/math/arm64/scalbn.c new file mode 100644 index 0000000..212752c --- /dev/null +++ b/mingw-w64-crt/math/arm64/scalbn.c @@ -0,0 +1,26 @@ +/** + * 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> + +double scalbn(double x, int exp) +{ + return x * exp2(exp); +} + +float scalbnf(float x, int exp) +{ + return x * exp2f(exp); +} + +long double scalbnl(long double x, int exp) +{ +#if defined(__aarch64__) || defined(_ARM64_) + return scalbn(x, exp); +#else +#error Not supported on your platform yet +#endif +} diff --git a/mingw-w64-crt/math/arm64/sincos.c b/mingw-w64-crt/math/arm64/sincos.c new file mode 100644 index 0000000..94f8244 --- /dev/null +++ b/mingw-w64-crt/math/arm64/sincos.c @@ -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 <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(__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/arm64/trunc.S b/mingw-w64-crt/math/arm64/trunc.S new file mode 100644 index 0000000..d784bf0 --- /dev/null +++ b/mingw-w64-crt/math/arm64/trunc.S @@ -0,0 +1,16 @@ +/** + * 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 "trunc.S" + .text + .p2align 2 + .globl __MINGW_USYMBOL(trunc) + .def __MINGW_USYMBOL(trunc); .scl 2; .type 32; .endef + +__MINGW_USYMBOL(trunc): + frintz d0, d0 + ret diff --git a/mingw-w64-crt/math/arm64/truncf.S b/mingw-w64-crt/math/arm64/truncf.S new file mode 100644 index 0000000..22b9ff8 --- /dev/null +++ b/mingw-w64-crt/math/arm64/truncf.S @@ -0,0 +1,16 @@ +/** + * 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 "truncf.S" + .text + .p2align 2 + .globl __MINGW_USYMBOL(truncf) + .def __MINGW_USYMBOL(truncf); .scl 2; .type 32; .endef + +__MINGW_USYMBOL(truncf): + frintz s0, s0 + ret diff --git a/mingw-w64-crt/math/fma.c b/mingw-w64-crt/math/fma.c index 645a3d1..c4ce738 100644 --- a/mingw-w64-crt/math/fma.c +++ b/mingw-w64-crt/math/fma.c @@ -17,6 +17,18 @@ double fma(double x, double y, double z){ return z; } +#elif defined(_ARM64_) || defined(__aarch64__) + +/* Use hardware FMA on ARM64. */ +double fma(double x, double y, double z){ + __asm__ ( + "fmadd %d0, %d1, %d2, %d0 \n" + : "+w"(z) + : "w"(x), "w"(y) + ); + return z; +} + #else long double fmal(long double x, long double y, long double z); diff --git a/mingw-w64-crt/math/fmaf.c b/mingw-w64-crt/math/fmaf.c index 9a0971d..b3f58a8 100644 --- a/mingw-w64-crt/math/fmaf.c +++ b/mingw-w64-crt/math/fmaf.c @@ -17,6 +17,18 @@ float fmaf(float x, float y, float z){ return z; } +#elif defined(_ARM64_) || defined(__aarch64__) + +/* Use hardware FMA on ARM64. */ +float fmaf(float x, float y, float z){ + __asm__ ( + "fmadd %s0, %s1, %s2, %s0 \n" + : "+w"(z) + : "w"(x), "w"(y) + ); + return z; +} + #else long double fmal(long double x, long double y, long double z); diff --git a/mingw-w64-crt/math/lrint.c b/mingw-w64-crt/math/lrint.c index c97e036..ec80e4e 100644 --- a/mingw-w64-crt/math/lrint.c +++ b/mingw-w64-crt/math/lrint.c @@ -16,6 +16,11 @@ long lrint (double x) "vcvtr.s32.f64 %[tmp], %[src]\n\t" "fmrs %[dst], %[tmp]\n\t" : [dst] "=r" (retval), [tmp] "=t" (temp) : [src] "w" (x)); +#elif defined(__aarch64__) || defined(_ARM64_) + __asm__ __volatile__ ( + "frintx %d1, %d1\n\t" + "fcvtzs %w0, %d1\n\t" + : "=r" (retval), "+w" (x)); #endif return retval; } diff --git a/mingw-w64-crt/math/lrintf.c b/mingw-w64-crt/math/lrintf.c index fadc29d..91fc5e1 100644 --- a/mingw-w64-crt/math/lrintf.c +++ b/mingw-w64-crt/math/lrintf.c @@ -15,6 +15,11 @@ long lrintf (float x) "vcvtr.s32.f32 %[src], %[src]\n\t" "fmrs %[dst], %[src]\n\t" : [dst] "=r" (retval), [src] "+w" (x)); +#elif defined(__aarch64__) || defined(_ARM64_) + __asm__ __volatile__ ( + "frintx %s1, %s1\n\t" + "fcvtzs %w0, %s1\n\t" + : "=r" (retval), "+w" (x)); #endif return retval; } diff --git a/mingw-w64-crt/math/rint.c b/mingw-w64-crt/math/rint.c index 8d69075..d883314 100644 --- a/mingw-w64-crt/math/rint.c +++ b/mingw-w64-crt/math/rint.c @@ -17,6 +17,8 @@ double rint (double x) { "vcvtr.s32.f64 %[tmp], %[src]\n\t" "vcvt.f64.s32 %[dst], %[tmp]\n\t" : [dst] "=w" (retval), [tmp] "=t" (temp) : [src] "w" (x)); +#elif defined(__aarch64__) || defined(_ARM64_) + __asm__ __volatile__ ("frintx %d0, %d1\n\t" : "=w" (retval) : "w" (x)); #endif return retval; } diff --git a/mingw-w64-crt/math/rintf.c b/mingw-w64-crt/math/rintf.c index 46b3a47..bfae515 100644 --- a/mingw-w64-crt/math/rintf.c +++ b/mingw-w64-crt/math/rintf.c @@ -16,6 +16,8 @@ float rintf (float x) { "vcvtr.s32.f32 %[dst], %[src]\n\t" "vcvt.f32.s32 %[dst], %[dst]\n\t" : [dst] "=t" (retval) : [src] "w" (x)); +#elif defined(__aarch64__) || defined(_ARM64_) + __asm__ __volatile__ ("frintx %s0, %s1\n\t" : "=w" (retval) : "w" (x)); #endif return retval; } diff --git a/mingw-w64-crt/math/sqrt.def.h b/mingw-w64-crt/math/sqrt.def.h index eaba8e0..041bc82 100644 --- a/mingw-w64-crt/math/sqrt.def.h +++ b/mingw-w64-crt/math/sqrt.def.h @@ -77,6 +77,12 @@ __FLT_ABI (sqrt) (__FLT_TYPE x) #else asm ("fsqrtd %[dst], %[src];\n" : [dst] "=w" (res) : [src] "w" (x)); #endif +#elif defined(__aarch64__) || defined(_ARM64_) +#if _NEW_COMPLEX_FLOAT + asm ("fsqrt %s[dst], %s[src]\n" : [dst] "=w" (res) : [src] "w" (x)); +#else + asm ("fsqrt %d[dst], %d[src]\n" : [dst] "=w" (res) : [src] "w" (x)); +#endif #elif defined(_X86_) || defined(__i386__) || defined(_AMD64_) || defined(__x86_64__) asm ("fsqrt" : "=t" (res) : "0" (x)); #else -- 2.7.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public