[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [avr-gcc-list] Detecting ++/-- overflow
From: |
David Brown |
Subject: |
Re: [avr-gcc-list] Detecting ++/-- overflow |
Date: |
Wed, 28 May 2003 09:00:54 +0200 |
> Speaking of overflows... what's an efficient way to detect when an
> increment or decrement results in an over- or underflow?
>
> Here's what I'm doing now:
>
> signed int counter, overflow;
>
> // Increment counter
> if (counter == INT_MAX) {
> counter = INT_MIN;
> overflow++;
> } else {
> counter++;
> }
>
> But you'd like to do something more like this: (I say this not having
> written assembly in a long time)
>
> counter++;
> if (bit_is_set(SREG, V)) {
> overflow++;
> }
>
> I don't know what you can count on the status register being preserved,
> though, and I don't really know how multiple byte and signed/unsigned
> types are handled. Looks like the INC instruction sets the overflow (V)
> flag for signed overflow only...
>
>From your first example, it looks like you were looking for singed types.
For unsigned types, I think it might be a bit easier. Here's some ideas - I
haven't tried compiling them to see the code generated, but they might be of
interest.
1) Use a long/struct typedef:
union { unsigned long big; struct { unsigned int counter, overflow; }; }
bigCounter;
Then use "bigCounter.big++" for your increment, and read
bigCounter.counter or bigCounter.overflow as needed. You could make "big"
and "overflow" signed, but not counter (your overflows would occur on the -1
to 0 transition).
2) For unsigned, you can use:
if (!(++counter)) overflow++;
I don't know whether gcc will generate a seperate test for zero, or whether
it can use the flags from the ++counter directly.
3) Your "bit_is_set(SREG, V)" trick should work fine. Use "V" for signed
counters, "C" for unsigned counters.
mvh.
David