Replace fixed point multiplication with C++ implementation

Fixed point multiplication used an ARM inline assembly routine. This was
fast, but unfortunately, caused some odd attempted inlining problems
when used from Thumb-mode code. This commit replaces this assembly
routine with a C++ implementation that performs equal or better than the
assembly routine in most cases. The C++ implementation is slightly
slower when called from Thumb-mode code because GCC inlines the
operation instead of calling a standalone ARM-mode routine placed in
IWRAM. The performance tradeoff is acceptable though because of the
fixes, portability, and ARM-mode performance improvements it provides.
This commit is contained in:
Madeline Busig 2024-08-03 16:08:22 -06:00
parent cc7c346f84
commit 5e4c492894

View File

@ -125,25 +125,11 @@ public:
/**
* \brief Fixed point multiplication
*
* Uses an assembly implementation to multiply the two numbers.
*/
fixed operator*(fixed rhs) const {
int32_t raw_result;
asm(
".arm;"
"smull r8, r9, %[a], %[b];"
"lsr %[res], r8, #6;"
"orr %[res], r9, lsl #26;"
: [res] "=r" (raw_result)
: [a] "r" (x),
[b] "r" (rhs.x)
: "r8", "r9"
);
return from_raw(raw_result);
constexpr fixed operator*(fixed rhs) const {
return from_raw(((int64_t)x * rhs.x) >> 6);
}
fixed& operator*=(fixed rhs) {
constexpr fixed& operator*=(fixed rhs) {
*this = *this * rhs;
return *this;
}