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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Avr-gcc Produces Incorrect Code with -Os


From: David Brown
Subject: Re: [avr-gcc-list] Avr-gcc Produces Incorrect Code with -Os
Date: Thu, 15 May 2008 20:38:25 +0200
User-agent: Thunderbird 2.0.0.14 (Windows/20080421)

Thomas D. Dean wrote:
I have a code segment which 1. sets a bit in PORTA.
  2.  calls atan2.
  3.  clears the same bit in PORTA.

The compiler produces code that 1. sets the bit in PORTA.
  2.  clears the same bit in PORT.
  3.  calls atan2.

With -O0, the code is correct.

# uname -a
FreeBSD dv6000.tddhome 7.0-STABLE FreeBSD 7.0-STABLE #0: Sun May  4 07:58:25 
PDT 2008     address@hidden:/usr/src/sys/GENERIC  i386

# avr-gcc --version
avr-gcc (GCC) 4.2.2
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

The code fragment,

  ...
  dtostrf(cos_rad,6,3,&line4[14]);
  line3[20] = ' ';
  line4[20] = ' ';
  TRACE_ON(TRACE4);  // portb |= _bv(04)
atan_rad = atan2(cos_rad,sin_rad); TRACE_OFF(TRACE4); // portb &= ~_bv(04)
  dtostrf(atan_rad,6,3,&line4[26]); 
  ...

As others have said, the compiler can freely move the atan2 call around. The easiest way to avoid that here is to declare "atan_rad" as volatile (to stop it moving past the TRACE_OFF), and either "cos_rad" or "sin_rad" as volatile (to stop it moving before the TRACE_ON). You can also try using a memory barrier (asm volatile("" : : : "memory") ) as a blocker, if the *_rad variables are in memory rather than being local variables.





reply via email to

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