diff options
| author | flatmush <flatmush@d3e1167c-abe1-51d5-8199-f9061ebe54e4> | 2011-02-28 09:59:36 +0000 |
|---|---|---|
| committer | flatmush <flatmush@d3e1167c-abe1-51d5-8199-f9061ebe54e4> | 2011-02-28 09:59:36 +0000 |
| commit | 8737eb5fe2796f1f550a131e8566d8d667f3024a (patch) | |
| tree | 2e4390dfa3e9f0e5a28958e495f6839f9cfe42fd | |
| parent | 5dd63f37ce73be2d36bb0ded9c7d8ba84932ccb7 (diff) | |
| download | libfixmath-8737eb5fe2796f1f550a131e8566d8d667f3024a.tar.gz | |
Added FIXMATH_NO_64BIT macro.
Implemented multiplication and signed multiplication in 32-bit.
| -rw-r--r-- | libfixmath/fix16.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/libfixmath/fix16.c b/libfixmath/fix16.c index 63cdbc6..2e3b6d5 100644 --- a/libfixmath/fix16.c +++ b/libfixmath/fix16.c @@ -28,15 +28,33 @@ fix16_t fix16_sadd(fix16_t inArg0, fix16_t inArg1) { fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1) {
+ #ifndef FIXMATH_NO_64BIT
int64_t tempResult = ((int64_t)inArg0 * (int64_t)inArg1);
#ifndef FIXMATH_NO_ROUNDING
tempResult += (fix16_one >> 1);
#endif
tempResult >>= 16;
return tempResult;
+ #else
+ int16_t hi[2] = { (inArg0 >> 16), (inArg1 >> 16) };
+ uint16_t lo[2] = { (inArg0 & 0xFFFF), (inArg1 & 0xFFFF) };
+
+ int32_t r_hi = hi[0] * hi[1];
+ int32_t r_md = (hi[0] * lo[1]) + (hi[1] * lo[0]);
+ uint32_t r_lo = lo[0] * lo[1];
+ #ifndef FIXMATH_NO_ROUNDING
+ r_lo += 0xFFFF;
+ #endif
+
+ r_md += (r_hi & 0xFFFF) << 16;
+ r_md += (r_lo >> 16);
+
+ return r_md;
+ #endif
}
fix16_t fix16_smul(fix16_t inArg0, fix16_t inArg1) {
+ #ifndef FIXMATH_NO_64BIT
int64_t tempResult = ((int64_t)inArg0 * (int64_t)inArg1);
#ifndef FIXMATH_NO_ROUNDING
tempResult += (fix16_one >> 1);
@@ -47,6 +65,24 @@ fix16_t fix16_smul(fix16_t inArg0, fix16_t inArg1) { if(tempResult > fix16_MAX)
return fix16_MAX;
return tempResult;
+ #else
+ int16_t hi[2] = { (inArg0 >> 16), (inArg1 >> 16) };
+ int32_t r_hi = hi[0] * hi[1];
+ if(r_hi >> 16)
+ return (r_hi < 0 ? fix16_MIN : fix16_MAX);
+
+ uint16_t lo[2] = { (inArg0 & 0xFFFF), (inArg1 & 0xFFFF) };
+ int32_t r_md = (hi[0] * lo[1]) + (hi[1] * lo[0]);
+ uint32_t r_lo = lo[0] * lo[1];
+ #ifndef FIXMATH_NO_ROUNDING
+ r_lo += 0xFFFF;
+ #endif
+
+ r_md += (r_hi & 0xFFFF) << 16;
+ r_md += (r_lo >> 16);
+
+ return r_md;
+ #endif
}
|
