[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
FW: [avr-gcc-list] Avr-gcc Produces Incorrect Code with -Os
From: |
Ron Kreymborg |
Subject: |
FW: [avr-gcc-list] Avr-gcc Produces Incorrect Code with -Os |
Date: |
Fri, 23 May 2008 20:31:00 +1000 |
> DECLARE_CRITICAL_SECTION - at the top of each function with a critical
> section - creates a variable to store SREG
> BEGIN_CRITICAL_SECTION - records the value of SREG and clears global
> interrupt flag
> END_CRITICAL_SECTION - restores SREG
>
> Technically it's no better than doing the code inline, but it is more
> self-documenting.
Like many others, I define a header file to provide a space in time in which
I can be sure no other events are occurring. Defining them as functions
ensures no compiler re-ordering. With -Os these reduce to the assembly code:
in r24, 0x3f
cli
and
out 0x3f, r24
Very concise. Even when they enclose quite complex statements gcc just keeps
moving that initial r24 contents around and eventually correctly restores
it.
However I like the idea of a "monitor" function attribute that would insert
a similar sequence automatically on entry and exit. We could then be sure no
compiler optimizations of any level would upset the internal sequence. The
challenge would be ensuring the saved SREG survived any complexity of
intervening code.
Ron
My (cutdown) header file:
typedef uint8 STATE_REG; // for AVR
static inline STATE_REG SaveState(void)
{
STATE_REG flags = SREG;
cli();
return flags;
}
static inline void RestoreState(STATE_REG ps) {
SREG = ps;
}
#define CRITICAL_ENTER STATE_REG state = SaveState()
#define CRITICAL_EXIT RestoreState(state)
- Re: [avr-gcc-list] Avr-gcc Produces Incorrect Code with -Os, (continued)