too much otimization

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a small (in fact a little theoretical) problem with AVR-GCC compiler.

I need compute delta value between two timestamps. Because system timer should wrap after reaching 0xFFFF the calucation function should take care about it. I also want use -O2 optimalization and no long int arithmetic.
The naive and obvius approach:
uint16_t timedelta(uint16_t t1, uint16_t t2)
{
if ( t2 >= t1 )
{
return t2 - t1;
}
else
{
return 0xFFFF - (t1 - t2) + 1;
}
}
does not work, it produces following assembly:
mov r18, r24
mov r19, r25
mov r25, r23
mov r24, r22
sub r24, r18
sbc r25, r19
ret

I end up in following code, but it is ugly.
uint16_t tmp;
....
else
{
t2++;
tmp = t1 - t2;
return 0xFFFF - tmp;
}

Is it possible to write that in more smarter way?

BTW> I am using latest AVR-binutils, GCC and libc snapshots (on Linux).

Regards,

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The optimizer is right. You're thinking wrong. :-)

IOW: you don't need to care at all for the timer
rollover (unless the timer might roll over twice, of
course).

Just return t2 - t1, that's all.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I expected that first approach will not work beacause of optimizer and undefined order of expression evaluation in C.

Thanks, I had feeling that it is very easy but I concentrated on "fight" with optimizer instead just to use brain.

Reagrds,