Why compiler did this

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

Hello guys.
I was wondering wath the compiler does with my c code.

DDRF |= 0xFF;
dc: 80 91 61 00 lds r24, 0x0061
e0: 8f ef ldi r24, 0xFF ; 255
e2: 80 93 61 00 sts 0x0061, r24

This is what was in my lss file.

I think the first line is not needed here am i correct

used: last winavr and optimazation s

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

Looks good to me. Read DDRF and discard. Then write 0xFF to DDRF.
Some registers need to be physically read for whatever reason. The compiler would have to be pretty smart trying to optimize that out.

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

I am new to AVR, but I would agree with ahank, some interrupt flags can be cleared on reads.

Anyway, a quick solution would be to set
DDRF = 0xFF directly.

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

Apparently the compiler was smart enough to know that ORing something with 0xFF would be the same as just setting it to 0xFF, but not smart enough to realize that you don't need the original value of DDRF. But as jlau81 says, making it '=' instead of '|=' should solve the problem.

Regards,
Steve A.

The Board helps those that help themselves.

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

Quote:
not smart enough to realize that you don't need the original value of DDRF

DDRF is declared "volatile", so the compiler had no choice. If the statement had simply been:

DDRF;

the compiler still would have had to generate the read.

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

I agree that writing DDRF = 0xFF is the same but just want to check out what the compiler does

Thanks for the input guys.

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

> but just want to check out what the compiler does

And so the compiler did *exactly* what you instructed
it to do. As mckenny wrote, as DDRF is declared volatile,
there's no chance of optimizing the read operation away.
If you want a read operation first, use |=, if you don't want
it, use a single = only.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

mckenney wrote:

DDRF is declared "volatile", so the compiler had no choice. If the statement had simply been:

DDRF;

the compiler still would have had to generate the read.

This is only true for C! In C++ a symbol name is parsed as a reference to the variable. This means that the (non-volatile) address can be safely optimized away. To get a (value discarded) read operation in C++ you should do this:

(char)DDRF;

which is also valid in C.

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

Better:

(void)DDRF;

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

Will that work Jörg? I'm asuming that you've tested it on something other than gcc because gcc and volatile are two things which don't mix very well... I've seen gcc brake any number of volatile-rules in the past.

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

> Will that work Jörg?

I think so. I'm a bit too lazy to dig up the standard around
that time of day now though.

> I'm asuming that you've tested it on something other than gcc

I currently don't have anything else but GCC here.

> because gcc and volatile are two things which don't mix very well...
> I've seen gcc brake any number of volatile-rules in the past.

Which GCC bug reports? Other references?

I've got the impression it's rather the other way round: some other
AVR compilers are more forgiving about forgotten "volatile"
qualifiers, while is more aggressive in optimizing seemingly unused
code away unless it refers to a volatile object.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

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

dl8dtl wrote:
> because gcc and volatile are two things which don't mix very well...
> I've seen gcc brake any number of volatile-rules in the past.

Which GCC bug reports? Other references?

I can't say for sure which gcc bug reports to refere to. The code I looked at was from versions that were "unstable" or using target code "under development" so it may very well be the target code that was broken and not the gcc code.

The code was something like this:

(void)"reference to volatile member in struct";

which got completely optimized away. It was in gcc 4.0.0.

dl8dtl wrote:
I've got the impression it's rather the other way round: some other
AVR compilers are more forgiving about forgotten "volatile"
qualifiers, while is more aggressive in optimizing seemingly unused
code away unless it refers to a volatile object.

Well, you basically get what you pay for. I wouldn't really complain if my $10 compiler doesn't work exactly as the standard says but I would complain if a $200 compiler was broken.

Gcc on the other hand has the advantage of beeing properly maintained so I would complain if it doesn't work even though it's for free. :-)