avr-gcc-list
[Top][All Lists]
Advanced

[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)






reply via email to

[Prev in Thread] Current Thread [Next in Thread]