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:
parent
cc7c346f84
commit
5e4c492894
@ -125,25 +125,11 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Fixed point multiplication
|
* \brief Fixed point multiplication
|
||||||
*
|
|
||||||
* Uses an assembly implementation to multiply the two numbers.
|
|
||||||
*/
|
*/
|
||||||
fixed operator*(fixed rhs) const {
|
constexpr fixed operator*(fixed rhs) const {
|
||||||
int32_t raw_result;
|
return from_raw(((int64_t)x * rhs.x) >> 6);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
fixed& operator*=(fixed rhs) {
|
constexpr fixed& operator*=(fixed rhs) {
|
||||||
*this = *this * rhs;
|
*this = *this * rhs;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user