Forum : ST7/STM8
Post Information | Post |
---|---|
May 17, 2011 - 8:32am
|
Please take a look at this function uint16_t val; uint16_t func2(void) In this case, val = 10. That means that the function should return 18000 * 10 / 10 = 18000. But it actually return 4892. It is easy to understand how it could be 4892 since 18000*10 = 180000 = 0x0002BF20, cut the 2 most significant bytes and you have 0xBF20, divide by 10 and we have 0x131c = 4892 . If we change one line in the function from “w /= val; “ to “w = w / val;” the return value is correct (18000). So there seems to be something strange with the '/=' operator! The generated assembler code look like this ; FUNCTION ?func2 (BEGIN) This does not look right to me. It seems that the function calculates the result of 0xBF20 / 10 which is what we get though it is incorrect. This is the complete source file if you want to compile it yourself. #include typedef unsigned char uint8_t; uint16_t val; char buf[100]; uint16_t func2(void) void main(void) My tools: I am compiling for the STM8 family, SCINAME(STM8). Target CPU is STM8S207M8. Best Regards |
Hi Andreas,
Thanks for this report.
We have been able to reproduce this behavior in our Labs.
The problem comes from a bug in our compiler: The constant propagation "inverts" the order of evaluation hence forgets the (uint32_t) cast. This is technically present in all binary operators, but it is visible only for multiplication, addition and left shift, only in the case where both operands are constants (or propagated constants as in your case) and one of them is cast from 16 to 32 bits.
This makes it a low exposure bug.
The bug will be fixed in our next RKit-STM8 release which will be available soon (next week hopefully).
The workaround is to rewrite the code a little bit so that the constant is not cast to 32-bits anymore. Just keeping the variable t as a long (uint32_t) is enough in your case.
Sorry for the inconvenience.
Best Regards,