Hello,
My function calculates scalar value from dB value using formular scalar = 10 ^ (dB / 20)
In case of ARMCLANG V6.12 and Optimizer Level -O2 the calculation fails as it is shown in my test code.
Maybe, I overlook something, do I?
#include "stm32f4xx.h" #include <stdio.h> #include <stdint.h> #include <math.h> static volatile int8_t dB; static int8_t lastGain; /**/ void setGain(int8_t gain) { float vol; if (lastGain == gain) { // value is already set return; } // calculate scalar value vol = powf(10.f, (float)gain / 20.f); // = 0.199526... // check limits if (vol > 10) { // "vol out of range" is printed in case of ARMCLANG V6.12 and Optimization > -O2 printf("vol out of range\n"); } else { // "passed" is printed in case of ARMCLANG V6.12 and Optimization -O0 or -O1 printf("passed\n"); lastGain = gain; } } /**/ int main(void) { dB = -14; for(;;) { setGain(dB); } }
"gain" value is 0xFFFFFFF2 (-14) on function setGain entry which is correct.
Actually, if that were the case, it would not be correct. The value of "gain" cannot be that --- because that value is way too large to fit into the int8_t type.
Now, the CPU register holding the value may contain all those bytes, but only one of those can be "gain" itself.
The actual problem then would be a failure to sign-extend this single byte before passing it to a compiler intrinsic function that expects to be fed a 32-bit value.