As Russell Shaw wrote:
uint16_t baud=9600
uint16_t reg=16000000/(16*baud) - 1;
what about __udivmodsi4?
Yeah. I didn't assume such poor optimization.
In the real code, uint16_t baud was set at 9600 using a const
literal passed as an array parameter.
As Eric just closed the bug report as being unreproducible, I gave it
a try to simulate your example code. I cannot reproduce any ``jumps
to nowhere'' behaviour though (and thus basically confirm Eric's
judgement).
However, your above example miscalculates `reg', as the expression
``16*baud'' is computed in uint16_t domain but overflows it. The
result of this subexpression is 153600 but is truncated to 22528.
Maybe this is your problem?
Rewriting the second calculation as:
uint16_t reg=16000000/(16*(unsigned long)baud) - 1;
makes it work for me. Though this is technically right, I think
most people would prefer
uint16_t reg=16000000UL/(16*(unsigned long)baud) - 1;
instead to make it explicit that the clock frequency is also an
unsigned long (even though the C standard is on your side and you're
permitted to omit the `UL'). Writing the UL suffix is also sufficient
to force the entire expression into the UL domain, so this works, too:
uint16_t reg=16000000UL/(16*baud) - 1;
Still, I'd personally prefer the previous version since it makes it
explicit. C type promotion rules are often not easy to understand at
a first glance.