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); } }
vol = powf(10.f, (float)gain / 20.f); // = 0.199526...
Are you saying that's the value you expect it to be, or that's the value actually getting assigned to 'vol' ?
dB = -14;
you haven't specified a type for 'dB' ...
Yes, I am expecting 0.199526 and dB (decibel) is defined as static volatile int8_t dB
So again, as in your previous post, what debugging have you done to see where the "unexpected" behaviour originates ?
What result are you getting for that calculation in the target, and in the simulator.
Your code is just bog-standard 'C' - so what do you get if you build & run it with a native PC compiler?
http://www.keil.com/forum/64307/
Try following links for the requested informations
uVision Projekt www.file-upload.net/.../uVision-test.zip.html
Screenshot of simulator www.file-upload.net/.../debug-out.png.html
Please reply in the forum.
The Project was created in Keil-MDK 5.27 for a Cortex M4 CPU It is compiled with Compiler V6.12 using optimization Level -O2 stdout is retarged to ITM Running the Code in Simulator is showing "vol out of range" in debug (printf) Viewer This is not what I would expect because the result of the calculation must be smaller than 10. This issue does not occur with V5.06
1. What result do you get for the calculation when running in the simulator?
2. What result do you get for the calculation when running in the real target?
3. What result do you get for the calculation when running on a PC?
I have quickly looked into this and I can replicate the behavior (either on target or simulator).
It looks like the compiler optimization incorrectly converts "(float)gain" into 242.0f instead of -14.0f.
"gain" value is 0xFFFFFFF2 (-14) on function setGain entry which is correct. However due to the comparison with lastGain the value gets truncated to 0x000000F2 and then later reused to convert to float which results in incorrect value 242.0f.
I have created a support ticket for this problem.
"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.