mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
AK: Add support for some trivial math functions on aarch64
These all require just a single instruction each, we only have to differentiate between register prefixes accordingly.
This commit is contained in:
parent
650d2fdc2d
commit
eb5651870e
Notes:
sideshowbarker
2024-07-17 05:58:44 +09:00
Author: https://github.com/Hendiadyoin1 Commit: https://github.com/SerenityOS/serenity/commit/eb5651870e Pull-request: https://github.com/SerenityOS/serenity/pull/15564 Reviewed-by: https://github.com/linusg
1 changed files with 85 additions and 0 deletions
85
AK/Math.h
85
AK/Math.h
|
@ -55,6 +55,24 @@ constexpr size_t product_odd() { return value * product_odd<value - 2>(); }
|
|||
return __builtin_##function##f(args); \
|
||||
}
|
||||
|
||||
#define AARCH64_INSTRUCTION(instruction, arg) \
|
||||
if constexpr (IsSame<T, long double>) \
|
||||
TODO(); \
|
||||
if constexpr (IsSame<T, double>) { \
|
||||
double res; \
|
||||
asm(#instruction " %d0, %d1" \
|
||||
: "=w"(res) \
|
||||
: "w"(##arg)); \
|
||||
return res; \
|
||||
} \
|
||||
if constexpr (IsSame<T, float>) { \
|
||||
float res; \
|
||||
asm(#instruction " %s0, %s1" \
|
||||
: "=w"(res) \
|
||||
: "w"(##arg)); \
|
||||
return res; \
|
||||
}
|
||||
|
||||
namespace Division {
|
||||
template<FloatingPoint T>
|
||||
constexpr T fmod(T x, T y)
|
||||
|
@ -110,6 +128,8 @@ constexpr T sqrt(T x)
|
|||
: "=t"(res)
|
||||
: "0"(x));
|
||||
return res;
|
||||
#elif ARCH(AARCH64)
|
||||
AARCH64_INSTRUCTION(fsqrt, x);
|
||||
#else
|
||||
return __builtin_sqrt(x);
|
||||
#endif
|
||||
|
@ -118,6 +138,9 @@ constexpr T sqrt(T x)
|
|||
template<FloatingPoint T>
|
||||
constexpr T rsqrt(T x)
|
||||
{
|
||||
#if ARCH(AARCH64)
|
||||
AARCH64_INSTRUCTION(frsqrte, x);
|
||||
#endif
|
||||
return (T)1. / sqrt(x);
|
||||
}
|
||||
|
||||
|
@ -214,6 +237,8 @@ constexpr T fabs(T x)
|
|||
"fabs"
|
||||
: "+t"(x));
|
||||
return x;
|
||||
#elif ARCH(AARCH64)
|
||||
AARCH64_INSTRUCTION(abs, x);
|
||||
#else
|
||||
return __builtin_fabs(x);
|
||||
#endif
|
||||
|
@ -581,6 +606,61 @@ ALWAYS_INLINE I round_to(P value)
|
|||
: "st");
|
||||
}
|
||||
return static_cast<I>(ret);
|
||||
#elif ARCH(AARCH64)
|
||||
if constexpr (IsSigned<I>) {
|
||||
if constexpr (sizeof(I) <= sizeof(i32)) {
|
||||
i32 res;
|
||||
if constexpr (IsSame<P, float>) {
|
||||
asm("fcvtns %w0, %s1"
|
||||
: "=r"(res), "w"(value));
|
||||
} else if constexpr (IsSame<P, double>) {
|
||||
asm("fcvtns %w0, %d1"
|
||||
: "=r"(res), "w"(value));
|
||||
} else if constexpr (IsSame<P, long double>) {
|
||||
TODO();
|
||||
}
|
||||
return static_cast<I>(res);
|
||||
}
|
||||
static_cast<sizeof(I) == 8>; // either long or long long aka i64
|
||||
i64 res;
|
||||
if constexpr (IsSame<P, float>) {
|
||||
asm("fcvtns %0, %s1"
|
||||
: "=r"(res), "w"(value));
|
||||
} else if constexpr (IsSame<P, double>) {
|
||||
asm("fcvtns %0, %d1"
|
||||
: "=r"(res), "w"(value));
|
||||
} else if constexpr (IsSame<P, long double>) {
|
||||
TODO();
|
||||
}
|
||||
return static_cast<I>(res);
|
||||
}
|
||||
|
||||
if constexpr (sizeof(I) <= sizeof(u32)) {
|
||||
u32 res;
|
||||
if constexpr (IsSame<P, float>) {
|
||||
asm("fcvtnu %w0, %s1"
|
||||
: "=r"(res), "w"(value));
|
||||
} else if constexpr (IsSame<P, double>) {
|
||||
asm("fcvtnu %w0, %d1"
|
||||
: "=r"(res), "w"(value));
|
||||
} else if constexpr (IsSame<P, long double>) {
|
||||
TODO();
|
||||
}
|
||||
return static_cast<I>(res);
|
||||
}
|
||||
|
||||
static_cast<sizeof(I) == 8>; // either unsigned long or unsigned long long aka u64
|
||||
u64 res;
|
||||
if constexpr (IsSame<P, float>) {
|
||||
asm("fcvtnu %0, %s1"
|
||||
: "=r"(res), "w"(value));
|
||||
} else if constexpr (IsSame<P, double>) {
|
||||
asm("fcvtnu %0, %d1"
|
||||
: "=r"(res), "w"(value));
|
||||
} else if constexpr (IsSame<P, long double>) {
|
||||
TODO();
|
||||
}
|
||||
return static_cast<I>(res);
|
||||
#else
|
||||
if constexpr (IsSame<P, long double>)
|
||||
return static_cast<I>(__builtin_llrintl(value));
|
||||
|
@ -676,10 +756,15 @@ constexpr T ceil(T num)
|
|||
? static_cast<i64>(num)
|
||||
: static_cast<i64>(num) + ((num > 0) ? 1 : 0);
|
||||
}
|
||||
#if ARCH(AARCH64)
|
||||
AARCH64_INSTRUCTION(frintp, num);
|
||||
#else
|
||||
return __builtin_ceil(num);
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef CONSTEXPR_STATE
|
||||
#undef AARCH64_INSTRUCTION
|
||||
}
|
||||
|
||||
using AK::round_to;
|
||||
|
|
Loading…
Reference in a new issue