diff options
author | Mark Kriegsman <kriegsman@tr.org> | 2016-01-07 23:01:20 +0300 |
---|---|---|
committer | Mark Kriegsman <kriegsman@tr.org> | 2016-01-07 23:01:20 +0300 |
commit | 0f146d5542ad77037b9954fd05843c6526878574 (patch) | |
tree | ed38def8283176789409f0aa1cbbc944316f74fb | |
parent | 78ad4262051fca6f8efcf75fbdd2993b3adb2dda (diff) |
scale16 faster and smaller - no need to initialize 'result' to zero since we're going to overwrite it. A little gcc asm shenanigans required to get this all right in terms of '=r' versus '+r' on the variable usage tag in the asm block. Basically the = versus + don't want to think about multi-byte variables. Coincidentally, neither do I.
-rw-r--r-- | lib8tion/scale8.h | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/lib8tion/scale8.h b/lib8tion/scale8.h index 239e9dea..e6bdeefd 100644 --- a/lib8tion/scale8.h +++ b/lib8tion/scale8.h @@ -388,8 +388,7 @@ LIB8STATIC uint16_t scale16( uint16_t i, fract16 scale ) result = ((uint32_t)(i) * (uint32_t)(scale)) / 65536; return result; #elif SCALE16_AVRASM == 1 - uint32_t result = 0; - const uint8_t zero = 0; + uint32_t result; asm volatile( // result.A-B = i.A x scale.A " mul %A[i], %A[scale] \n\t" @@ -406,12 +405,26 @@ LIB8STATIC uint16_t scale16( uint16_t i, fract16 scale ) // well, in case we want to use this code for // a generic 16x16 multiply somewhere. + : [result] "=r" (result) + : [i] "r" (i), + [scale] "r" (scale) + : "r0", "r1" + ); + + asm volatile( // result.C-D = i.B x scale.B " mul %B[i], %B[scale] \n\t" //" mov %C[result], r0 \n\t" //" mov %D[result], r1 \n\t" " movw %C[result], r0 \n\t" + : [result] "+r" (result) + : [i] "r" (i), + [scale] "r" (scale) + : "r0", "r1" + ); + const uint8_t zero = 0; + asm volatile( // result.B-D += i.B x scale.A " mul %B[i], %A[scale] \n\t" @@ -435,6 +448,7 @@ LIB8STATIC uint16_t scale16( uint16_t i, fract16 scale ) [zero] "r" (zero) : "r0", "r1" ); + result = result >> 16; return result; #else |