Re: [avr-gcc-list] Problem with delay loop

2007-10-03 Thread Paulo Marques

Dave Hansen wrote:

[...]
I don't remember the code.  Was the function declared static?  If not, 
the compiler must generate at least the ret since functions external to 
the file could potentially call it as well.  If the function was static, 
the code for it (and the calls to it) could indeed be removed entirely.


This is even better with "new and improved compilers": even if you don't 
declare the function static, but you compile your project with "-combine 
-fwhole-program", the compiler can still through it away entirely :)


For instance, I have a small project with several c modules, that when 
compiled with "-combine -fwhole-program" creates a 3kb .text section. If 
I place a "return 0" at the top of main, the compiler optimizes almost 
everything away and produces a 180 bytes .text section. Only the 
interrupt handlers survive, because we told the compiler explicitly not 
to through them away.


Note that I'm not advocating for not declaring static functions that 
should be static. Only that functions that can't be static because are 
used from outside its module can still be optimized by the compiler with 
this option.


The only downside is that this basically makes the compiler compile the 
entire project at once instead of just the modules with changes. For 
small projects, this isn't too bad at all, and for big projects you can 
do it for just the "final version".


--
Paulo Marques
Software Development Department - Grupo PIE, S.A.
Phone: +351 252 290600, Fax: +351 252 290601
Web: www.grupopie.com

"All I ask is a chance to prove that money can't make me happy."



___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-10-03 Thread David Brown

Royce Pereira wrote:

Hi,

On Mon, 01 Oct 2007 13:02:32 +0530, David Brown
<[EMAIL PROTECTED]> wrote:

Royce Pereira wrote:

So I have to write more 'C' code :) to get the same stuff done,
in the 'new & smarter' compiler! Interesting.

Doesn't seem right, some how.

Regards, --Royce.

It might not seem right, but that's the way it is.  The compiler
only has to generate code that has the same effect as the source
you've written, and a simple "ret" has that effect.


Why then was the empty 'ret' function retained?


If the function is globally visible (i.e., not static to the file), then
the compiler must generate a working function - "ret" is as small and
fast as it gets.


I would think such a case would be the prime candidate for
optimisation. The compiler should eliminate such a funtion, as well
as all calls to that function. That would really make a difference in
size/speed of the code.



The compiler will inline calls to the function in the same translation
unit, and thus eliminate the "ret".


(Instead, the compiler destroys a perfectly good delay loop I've used
for the last 2 years -yes, I'm still sore)


There is no way in C to express the idea of a time delay - the
language has no concept of time. Thus you have to go out of your
way to tell the compiler to be particularly stupid if you want this
sort of code to work.  There are other ways to get a delay, such as
the library routines or hardware timers, or by including something
like an "asm volatile ("nop")" in the loop, but using a volatile
loop counter is an easy way to get an approximate delay loop.


Of course, there's no disputing that. But the delay loop is just an
example, of how simple ,intuitive code can throw the compiler into a
tizzy. I've used SDCC(for mcs51) where the compiler 'recognises' code
patterns, and says "Oh, I know what this is - it's a delay loop! -
Let it pass."(for example).



That sounds to me like a very bad idea, as you'll find out the day you 
write a slightly unusual delay loop which is not pattern matched, and 
your code gets eliminated.



I've always maintained -  good software is one that does what you
*want* it to do, *not* what you tell it to do. ;)



I prefer software to do as I tell it, but perhaps to warn me if that's 
not what it thinks I mean.  Thus gcc will accept code like "if (a = 1) 
...", but will warn that it's probably not what I meant.  Of course, it 
would all be a lot easier if the language in question had a way to 
express what I want!



Regards, --Royce.




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-10-02 Thread Royce Pereira
Hi, David,

On Wed, 03 Oct 2007 02:24:16 +0530, David Kelly <[EMAIL PROTECTED]> wrote:

> So? Why did *you* change compilers if the old one did what you wanted?
> If it doesn't do what you want then its your choice whether to change
> your code to conform or to revert to the compiler that did what you
> want.

If you're interested, I've reverted back to the older compiler version.

>
>> Of course, there's no disputing that. But the delay loop is just an
>> example, of how simple ,intuitive code can throw the compiler into a
>> tizzy.
>
> Avr-gcc *has* a delay loop that the compiler recognizes and leaves
> alone. You've been told about  yet you have written
> more email than the amount of code you would have to change to use it.

Read again the lines preceding your comment. It's not just about a delay loop.

My 'problem' triggered a discussion 37 posts long (so far). Of which mine were 
just 6 (including the one that triggered the discussion). So the fact that 'I 
wrote more email than code' is incorrect.

I may be stupid & stll 'learning' as compared to other older members(who I 
highly respect), but, I beleive I'm entitled to politely express my opinion.

It's true I had a different understanding of compiler working (which others 
have made efforts to correct).

Does this deserve a attack from you at a personal level?

Cheers,
--Royce.
-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-10-02 Thread David Kelly
On Wed, Oct 03, 2007 at 12:23:46AM +0530, Royce Pereira wrote:
> 
> Why then was the empty 'ret' function retained?
> I would think such a case would be the prime candidate for
> optimisation.  The compiler should eliminate such a funtion, as well
> as all calls to that function.  That would really make a difference in
> size/speed of the code.
> 
> (Instead, the compiler destroys a perfectly good delay loop I've used
> for the last 2 years -yes, I'm still sore)

So? Why did *you* change compilers if the old one did what you wanted?
If it doesn't do what you want then its your choice whether to change
your code to conform or to revert to the compiler that did what you
want.

So says one who still maintains a project using the same C compiler from
1994.

*Always* archive the tools with your source code.

> Of course, there's no disputing that. But the delay loop is just an
> example, of how simple ,intuitive code can throw the compiler into a
> tizzy. I've used SDCC(for mcs51) where the compiler 'recognises' code
> patterns, and says "Oh, I know what this is - it's a delay loop! - Let
> it pass."(for example).
> 
> I've always maintained -  good software is one that does what you
> *want* it to do, *not* what you tell it to do. ;)

I'm always frightened when someone thinks they know better what I want
than what I said. Even more frightened when someone claims *software*
knows better.

Avr-gcc *has* a delay loop that the compiler recognizes and leaves
alone. You've been told about  yet you have written
more email than the amount of code you would have to change to use it.

-- 
David Kelly N4HHE, [EMAIL PROTECTED]

Whom computers would destroy, they must first drive mad.


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


RE: [avr-gcc-list] Problem with delay loop

2007-10-02 Thread Dave Hansen

> From: [EMAIL PROTECTED]
> 
> Hi,
> 
> On Mon, 01 Oct 2007 13:02:32 +0530, David Brown <[EMAIL PROTECTED]> wrote:
> > Royce Pereira wrote:
> >>
> >> So I have to write more 'C' code :) to get the same stuff done, in
> >> the 'new & smarter' compiler! Interesting.
> >>
> >> Doesn't seem right, some how.
> >>
> >> Regards, --Royce.
> >
> > It might not seem right, but that's the way it is.  The compiler only
> > has to generate code that has the same effect as the source you've
> > written, and a simple "ret" has that effect.
> 
> Why then was the empty 'ret' function retained?
> I would think such a case would be the prime candidate for optimisation.
> The compiler should eliminate such a funtion, as well as all calls to that 
> function.
> That would really make a difference in size/speed of the code.

I don't remember the code.  Was the function declared static?  If not, the 
compiler must generate at least the ret since functions external to the file 
could potentially call it as well.  If the function was static, the code for it 
(and the calls to it) could indeed be removed entirely.

Years ago, I ran a simple test on a compiler for the 80386.  The code

   static int square(int n)
   {
  return n*n;
   }

   int test(void)
   {
  return square(3);
   }

generated

   _test:
  mov ax,9
  ret

So in that case, no code was generated for the static function.

> 
> (Instead, the compiler destroys a perfectly good delay loop I've used for the 
> last 2 years -yes, I'm still sore)

Sorry, I must disagree.  It was not "perfectly good."  As the fact that the 
compiler was able to legally destroy it demonstrates.

[...]

> I've always maintained -  good software is one that does what you *want* it 
> to do, *not* what you tell it to do. ;)

Sorry, I must again disagree.  All too often, software that attempts to DWIM 
(Do What I Mean) guesses wrong, and I have to clean up a mess.  E.g., try 
entering acronyms in Microsoft Word, and watch it "correct" them for you.

Regards,

   -=Dave


_
Windows Live Hotmail and Microsoft Office Outlook – together at last.  Get it 
now.
http://office.microsoft.com/en-us/outlook/HA102225181033.aspx?pid=CL100626971033___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-10-02 Thread Royce Pereira
Hi,

On Mon, 01 Oct 2007 13:02:32 +0530, David Brown <[EMAIL PROTECTED]> wrote:
> Royce Pereira wrote:
>>
>> So I have to write more 'C' code :) to get the same stuff done, in
>> the 'new & smarter' compiler! Interesting.
>>
>> Doesn't seem right, some how.
>>
>> Regards, --Royce.
>
> It might not seem right, but that's the way it is.  The compiler only
> has to generate code that has the same effect as the source you've
> written, and a simple "ret" has that effect.

Why then was the empty 'ret' function retained?
I would think such a case would be the prime candidate for optimisation.
The compiler should eliminate such a funtion, as well as all calls to that 
function.
That would really make a difference in size/speed of the code.

(Instead, the compiler destroys a perfectly good delay loop I've used for the 
last 2 years -yes, I'm still sore)

> There is no way in C to
> express the idea of a time delay - the language has no concept of time.
>   Thus you have to go out of your way to tell the compiler to be
> particularly stupid if you want this sort of code to work.  There are
> other ways to get a delay, such as the library routines or hardware
> timers, or by including something like an "asm volatile ("nop")" in the
> loop, but using a volatile loop counter is an easy way to get an
> approximate delay loop.
>
Of course, there's no disputing that. But the delay loop is just an example, of 
how simple ,intuitive code can throw the compiler into a tizzy. I've used 
SDCC(for mcs51) where the compiler 'recognises' code patterns, and says "Oh, I 
know what this is - it's a delay loop! - Let it pass."(for example).

I've always maintained -  good software is one that does what you *want* it to 
do, *not* what you tell it to do. ;)

Regards,
--Royce.
-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


RE: [avr-gcc-list] Problem with delay loop

2007-10-02 Thread John Regehr
> Ah, ok then. In practice, I have never needed to use setjmp/longjmp, so I
> have a tendency to forget about these routines.

We should all be so lucky :).

John Regehr


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


RE: [avr-gcc-list] Problem with delay loop

2007-10-02 Thread Eric Weddington


> -Original Message-
> From:
> [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED]
> org] On Behalf Of Graham Davies
> Sent: Monday, October 01, 2007 6:56 PM
> To: 'AVR-GCC-LIST'
> Subject: Re: [avr-gcc-list] Problem with delay loop
>
> First point second.  I think I agree with you about the
> possibility of the
> compiler being really smart and figuring out that no way
> could a variable be
> seen outside of the local scope so to hell with it.  But, the
> standard
> doesn't take that approach so such a compiler would be
> non-standard.

Mmm. Good point.

Eric




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


RE: [avr-gcc-list] Problem with delay loop

2007-10-02 Thread Eric Weddington


> -Original Message-
> From:
> [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED]
> org] On Behalf Of David Brown
> Sent: Tuesday, October 02, 2007 2:48 AM
> To: 'AVR-GCC-LIST'
> Subject: Re: [avr-gcc-list] Problem with delay loop
>
> Graham Davies wrote:
> > Eric Weddington wrote:
> >> ... We were discussing the possibility of the compiler being
> >> smarter about 'volatile' and local automatic variables. I would
> >> definitely say that if the local variable's address is taken, then
> >> all bets are off.
> >
> > Second point first.  If the address of a variable is taken then the
> > compiler cannot put it in a register.  If it is declared automatic,
> > it goes on the stack, if there is one, or somewhere else in
> memory if
> > there
>
> Actually, you're slightly wrong on both accounts here.  On
> the AVR, the
> registers are available in the memory map, so it is possible to take
> their addresses (it's not commonly done, except perhaps on the old
> RAM-less Tiny's, but it's possible).

True. However in practice, I don't think the AVR port in GCC is aware of
these aliases and I don't think that it will use them.




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


RE: [avr-gcc-list] Problem with delay loop

2007-10-02 Thread Eric Weddington


> -Original Message-
> From: John Regehr [mailto:[EMAIL PROTECTED]
> Sent: Monday, October 01, 2007 10:59 PM
> To: Eric Weddington
> Cc: 'Paulo Marques'; 'David Brown'; 'AVR-GCC'
> Subject: RE: [avr-gcc-list] Problem with delay loop
>
> > However, David brings up a good point. A local variable is
> put on the stack,
> > generally not the place for hardware to modify the
> variable. And generally,
> > other parts of the program (such as ISRs) don't have access
> to the specific
> > location of the variable on the stack. Both hardware and
> ISRs work with
> > global variables. So *could* a compiler reason that local
> variables could
> > never be volatile? Or are there truly situations where
> hardware or ISRs
> > could modify local variables on the stack?
>
> The common use of volatile automatic variables is in conjunction with
> setjmp/longjmp.  This idiom would break if volatile locals went into
> registers.

Ah, ok then. In practice, I have never needed to use setjmp/longjmp, so I
have a tendency to forget about these routines.

Thanks,
Eric




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-10-02 Thread David Brown

Graham Davies wrote:

Eric Weddington wrote:

... We were discussing the possibility of the compiler being
smarter about 'volatile' and local automatic variables. I would
definitely say that if the local variable's address is taken, then
all bets are off.


Second point first.  If the address of a variable is taken then the 
compiler cannot put it in a register.  If it is declared automatic,

it goes on the stack, if there is one, or somewhere else in memory if
there


Actually, you're slightly wrong on both accounts here.  On the AVR, the
registers are available in the memory map, so it is possible to take
their addresses (it's not commonly done, except perhaps on the old
RAM-less Tiny's, but it's possible).  Secondly, "automatic" variables
can be allocated in registers - they don't have to go on the stack (or
in memory).


isn't.  We put the address of variables on the stack into globals at
our peril, but get away with it if we know what we're doing.  Nobody
 disagreed with any of this, but I thought it worth saying.




First point second.  I think I agree with you about the possibility
of the compiler being really smart and figuring out that no way could
a variable be seen outside of the local scope so to hell with it.
But, the standard doesn't take that approach so such a compiler would
be non-standard.  I disagree with the people saying that the standard
isn't very clear about what volatile means.  I think it's very clear.
A conforming compiler will never optimize away any access to a
volatile variable.  Nor will it perform additional accesses, for
example by using it to store intermediate values in a calculation.  I
think the idea that the standard isn't clear comes from
non-conforming compilers.



There are a few things regarding "volatile" that are not well specified
in the standards, and there are a few differences between the keyword in
C and C++ (just to add to the possible confusion).  As with many such
cases, these have little impact on well-written code in practice, but
they are still issues to consider:

http://gcc.gnu.org/onlinedocs/gcc/Volatiles.html

And to quote from
http://gcc.gnu.org/onlinedocs/gcc/Qualifiers-implementation.html:


However, if the volatile storage is not being modified, and the value
of the volatile storage is not used, then the situation is less
obvious. For example

volatile int *src = somevalue; *src;


According to the C standard, such an expression is an rvalue whose
type is the unqualified version of its original type, i.e. int.
Whether GCC interprets this as a read of the volatile object being
pointed to or only as a request to evaluate the expression for its
side-effects depends on this type.

If it is a scalar type, or on most targets an aggregate type whose
only member object is of a scalar type, or a union type whose member
objects are of scalar types, the expression is interpreted by GCC as
a read of the volatile object; in the other cases, the expression is
only evaluated for its side-effects.


mvh.,

David


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-10-02 Thread David Brown

Paulo Marques wrote:

David Brown wrote:

Paulo Marques wrote:

David Brown wrote:

[...]
it could perhaps reason that since there is no way for anything 
outside the program to find out where the local volatile variable 
resides, there is no way for anything else to influence or use the 
variable, and therefore the "volatile" qualifier can be ignored.


This sentence makes no sense at all. The "volatile" is precisely to 
warn the compiler that it should not "reason" anything about this 
variable.


I think the standards are pretty vague regarding exactly what 
"volatile" means.  There is nothing (that I know of) in the standards 
saying where a volatile variable must be allocated.


Yes, I wasn't disputing that either. Only that the compiler could not 
"reason" that it wasn't used.


Note that I'm not arguing the memory/register allocation here. You could 
also have a CPU that had a "register access counter", or something, 
where accessing a CPU register would increase the counter value and you 
wanted to use volatile to make the compiler access the register in the 
loop to increase the counter value.


If you give a volatile qualifier to a local variable, it's obvious 
that you want it to behave differently from regular local variables, 
so I think gcc is doing the best it can, from the weakly defined 
volatile semantics.


It may be obvious to *you*, as the author, that you mean "volatile" to 
work like this.  It certainly works like that on avr-gcc at the moment. 


The "obvious" part here is that you can declare a local variable without 
any modifiers or with the volatile modifier. If the volatile modifier 
makes the compiler generate the same code, then it would be useless. If 
it forces the compiler to not optimize away accesses to that variable, 
then it can have some use.




Just because the keyword "volatile" exists, does not automatically mean 
that it will cause different code to be generated!  The "register" 
qualifier is pretty much redundant on modern compilers.


 But what appears "obvious" to programmers (even expert experienced 
programmers), and what the standards say, what the compiler does, and 
how it all works on the target in question, can be very different 
things.  When working with bigger cpus with caches and instruction 
re-ordering, for example, "volatile" is not nearly strong enough to 
give you the kind of guarantees we take for granted on avr-gcc.


Yes, I follow LKML too, and all the endless threads on memory ordering / 
volatile / SMP races ;)




I don't follow the LKML (I check out the highlights occasionally), but 
I've seen it in practice with a couple of embedded processors.


This makes as much sense as saying that any volatile is futile, since 
you can compile a program with "-combine -whole-program" and so the 
compiler can always "reason" that any variable will not be accessed 
outside of its control.


No, it's not quite the same.  In particular, if the variable's address 
is known outside the code (for example, if it is given a fixed 
address, such as by the definition of the port I/O registers), then 
there is no way the compiler could make guarantees about the safety of 
removing the "volatile". 


I think you're actually agreeing with me that the compiler can not 
optimize global accesses away, but you're saying that it can for local 
variables because their locations aren't known?




That's pretty much the case, yes.  As I said, I don't know if that 
argument is valid (depending on the standards and the compiler's 
interpretation of the standards).  I'd just want to be sure before 
relying on particular behaviour.


Certainly if you have anything that depends on the behaviour of external 
influences on data whose address is unknown (alternatively, whose 
function is unknown for a given address), then your code is going to be 
unpredictable at best.  Is it valid for the compiler to assume that 
either you've written correct working code, and thus it can optimize it 
on that assumption, or otherwise you have written broken code, in which 
case it will do no harm by breaking it further?


Actually, I've thought of a couple of scenarios where there could be 
outside influence on data without the local symbols being exported or 
the addresses of the local variables being taken.  One is if you are 
running under a debugger or other program that has access to a symbol 
table, and the other is in conjunction with automatic garbage collection 
libraries or similar code that sweeps through memory.


What if the CPU had dedicated storage for the stack frame, and accessing 
locations there had side effects unknown to the compiler?


Yes, I'm grasping at straws here, but the bottom line is: if the side 
effects are unknown to the compiler, _they_ _are_ _unknown_ to the 
compiler. It is best not to assume anything.




I agree that it is best for the compiler not to assume anything.  I just 
wondering if that might apply to the programmer too!


Similarly, if different

RE: [avr-gcc-list] Problem with delay loop

2007-10-01 Thread John Regehr
> However, David brings up a good point. A local variable is put on the stack,
> generally not the place for hardware to modify the variable. And generally,
> other parts of the program (such as ISRs) don't have access to the specific
> location of the variable on the stack. Both hardware and ISRs work with
> global variables. So *could* a compiler reason that local variables could
> never be volatile? Or are there truly situations where hardware or ISRs
> could modify local variables on the stack?

The common use of volatile automatic variables is in conjunction with 
setjmp/longjmp.  This idiom would break if volatile locals went into 
registers.

Also there's no reason (in principle) that interrupts cannot access stack 
frames of non-interrupt contexts.

So anyway, I would say that regardless of what the standard actually says, 
it *should* specify that volatile locals behave similarly to volatile 
globals: loads and stores in the abstract machine must correspond 
one-to-one with loads and stores (to RAM, not registers) in the physical 
machine.

John Regehr


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-10-01 Thread Bob Paddock
On Monday 01 October 2007 09:48:23 am Eric Weddington wrote:

> Its an interesting question. I'm not sure what the answer is. Perhaps a
> language lawyer on comp.lang.c could explain the reasoning behind the
> current standard.

http://thread.gmane.org/gmane.linux.kernel/523210
for the Linux view on Volatile.

The links in the code below are worth following.

What follows is John Regehr's Volatile test case, from the Cyclone Compiler
list, see: http://www.nabble.com/volatile-tf4417773.html

"In case anyone's interested I'm attaching my test program.  The functions 
at the top of the file must compile to one load from x followed by one 
store to x.

Thanks,

John Regehr"


/*

add:
load and store conditional on constant, variable, etc.
more temptation for loop hoisting
short-circuit tests

possibility: generate all expressions of size <=N that result in an
lvalue pointing to x and/or and rvalue evaluating to x

also glue code into larger functions (or use inlining)

type multiple data widths, signed and unsigned, const volatile

might as well also test nonvolatile types...

goal: break gcc and Intel compilers!

ask who about this?  cyclone people, c0x people, ...

 volatile: structs, unions, arrays, ...

http://vstte.ethz.ch/pdfs/vstte-rushby-position.pdf
http://mir.cs.uiuc.edu/~marinov/publications/Marinov04TestingStructurallyComplexInputs.pdf
http://www.csl.sri.com/~rushby/papers/vstte07.ps.gz

- look up wording of volatile in C89, C99, C0x

- automate testing using an interpreter: look for loads and stores,
  this would allow systematic testing of option and program variants

- http://www.nullstone.com/htmls/category/volatile.htm

test:
  more gccs
  Realview ARM compiler
  Codewarrior for HC11
  LLVM
  LCC
  MSVC++
  IAR compilers
  win-avr
  win-arm
  msp430-gcc   

*/
 


// typedef unsigned int t;
typedef int t;

volatile t x;

void self_assign_1 (void)
{
  x = x;
}

void self_assign_2 (void)
{
  t sink = x;
  x = sink;
}

void self_assign_3 (void)
{
  volatile t *xp = &x;
  *xp = *xp;
}

void self_assign_4 (void)
{
  volatile t *xp = &x;
  t sink = *xp;
  *xp = sink;
}

void self_assign_5 (void)
{
  volatile t *xp1 = &x;
  volatile t *xp2 = &x;
  *xp1 = *xp2;
}

void self_assign_6 (void)
{
  volatile t *xp = &x;
  volatile t **xpp = &xp;
  t sink = **xpp;
  **xpp = sink;
}

void self_assign_7 (void)
{
  volatile t *xp1 = &x;
  volatile t *xp2 = &x;
  volatile t **xpp1 = &xp1;
  volatile t **xpp2 = &xp2;
  **xpp1 = **xpp2;
}

void self_assign_8 (void)
{
  volatile t *xp = &x;
  volatile t **xpp = &xp;
  t sink = *xp;
  **xpp = sink;
}

void self_assign_9 (void)
{
  volatile t *xp1 = &x;
  volatile t *xp2 = &x;
  volatile t **xpp2 = &xp2;
  *xp1 = **xpp2;
}

void self_assign_10 (void)
{
  volatile t *xp = &x;
  volatile t **xpp = &xp;
  t sink = **xpp;
  *xp = sink;
}

void self_assign_11 (void)
{
  volatile t *xp1 = &x;
  volatile t *xp2 = &x;
  volatile t **xpp1 = &xp1;
  **xpp1 = *xp2;
}

void or_1 (void)
{
  x |= 0;
}

void or_2 (void)
{
  x = x | 0;
}

void or_3 (void)
{
  t sink = x | 0;
  x = sink;
}

void or_4 (void)
{
  t zero = 0;
  t sink = x | zero;
  x = sink;
}

void or_5 (void)
{
  volatile t zero = 0;
  t sink = x | zero;
  x = sink;
}

void or_6 (void)
{
  t zero = 0;
  volatile t sink = x | zero;
  x = sink;
}

void and_1 (void)
{
  x &= ~0;
}

void and_2 (void)
{
  x = x & ~0;
}

void and_3 (void)
{
  t sink = x & ~0;
  x = sink;
}

void and_4 (void)
{
  t not_zero = ~0;
  t sink = x & not_zero;
  x = sink;
}

void and_5 (void)
{
  volatile t not_zero = ~0;
  t sink = x & not_zero;
  x = sink;
}

void and_6 (void)
{
  t not_zero = ~0;
  volatile t sink = x & not_zero;
  x = sink;
}

volatile t y;

void loop_1 (void)
{
  t i;
  t result = y;
  for (i=0; i<10; i++) {
result += x;
  }
  y = result;
}

void loop_2 (void)
{
  t i;
  for (i=0; i<10; i++) {
x += 3;
  }
}

void loop_3 (void)
{
  t i;
  volatile t z;
  for (i=0; i<10; i++) {
z += 3;
  }
}

void loop_4 (t n)
{
  t b;
  t res = 0;
  for (b=0; bhttp://www.wearablesmartsensors.com/
 http://www.softwaresafety.net/ http://www.designer-iii.com/
 http://www.unusualresearch.com/


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-10-01 Thread Graham Davies

Eric Weddington wrote:

... We were discussing the possibility of the
compiler being smarter about 'volatile' and
local automatic variables. I would definitely
say that if the local variable's address is taken,
then all bets are off.


Second point first.  If the address of a variable is taken then the compiler 
cannot put it in a register.  If it is declared automatic, it goes on the 
stack, if there is one, or somewhere else in memory if there isn't.  We put 
the address of variables on the stack into globals at our peril, but get 
away with it if we know what we're doing.  Nobody disagreed with any of 
this, but I thought it worth saying.


First point second.  I think I agree with you about the possibility of the 
compiler being really smart and figuring out that no way could a variable be 
seen outside of the local scope so to hell with it.  But, the standard 
doesn't take that approach so such a compiler would be non-standard.  I 
disagree with the people saying that the standard isn't very clear about 
what volatile means.  I think it's very clear.  A conforming compiler will 
never optimize away any access to a volatile variable.  Nor will it perform 
additional accesses, for example by using it to store intermediate values in 
a calculation.  I think the idea that the standard isn't clear comes from 
non-conforming compilers.


Graham.




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


RE: [avr-gcc-list] Problem with delay loop

2007-10-01 Thread Eric Weddington


> -Original Message-
> From: Preston Wilson [mailto:[EMAIL PROTECTED]
> Sent: Monday, October 01, 2007 8:13 AM
> To: Eric Weddington; 'Paulo Marques'; 'David Brown'
> Cc: AVR-GCC-LIST
> Subject: Re: [avr-gcc-list] Problem with delay loop
>
> "Eric Weddington" wrote:
>
> > ...
>
> > I agree with the statement above that "'volatile' is
> precisely to warn the
> > compiler that it should not 'reason' anything about [the] variable".
> > However, David brings up a good point. A local variable is
> put on the stack,
> > generally not the place for hardware to modify the
> variable. And generally,
> > other parts of the program (such as ISRs) don't have access
> to the specific
> > location of the variable on the stack. Both hardware and
> ISRs work with
> > global variables. So *could* a compiler reason that local
> variables could
> > never be volatile? Or are there truly situations where
> hardware or ISRs
> > could modify local variables on the stack?
>
> Yes, ISRs and hardware can modify variables on the stack.
>
> uint8_t *g1;
>
> ISR1()
> {
>  *g1 = 1;
> }
>
> main()
> {
>   volatile uint8_t v = 0;
>
>   g1 = &v;
>
>   // configure ISRs and enable interrupts
>   ...
> }

Sure, but only indirectly, through a global variable as I pointed out above.

I should have been more specific. We were discussing the possibility of the
compiler being smarter about 'volatile' and local automatic variables. I
would definitely say that if the local variable's address is taken, then all
bets are off.

Eric




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-10-01 Thread Paulo Marques

David Brown wrote:

Paulo Marques wrote:

David Brown wrote:

[...]
it could perhaps reason that since there is no way for anything 
outside the program to find out where the local volatile variable 
resides, there is no way for anything else to influence or use the 
variable, and therefore the "volatile" qualifier can be ignored.


This sentence makes no sense at all. The "volatile" is precisely to 
warn the compiler that it should not "reason" anything about this 
variable.


I think the standards are pretty vague regarding exactly what "volatile" 
means.  There is nothing (that I know of) in the standards saying where 
a volatile variable must be allocated.


Yes, I wasn't disputing that either. Only that the compiler could not 
"reason" that it wasn't used.


Note that I'm not arguing the memory/register allocation here. You could 
also have a CPU that had a "register access counter", or something, 
where accessing a CPU register would increase the counter value and you 
wanted to use volatile to make the compiler access the register in the 
loop to increase the counter value.


If you give a volatile qualifier to a local variable, it's obvious 
that you want it to behave differently from regular local variables, 
so I think gcc is doing the best it can, from the weakly defined 
volatile semantics.


It may be obvious to *you*, as the author, that you mean "volatile" to 
work like this.  It certainly works like that on avr-gcc at the moment. 


The "obvious" part here is that you can declare a local variable without 
any modifiers or with the volatile modifier. If the volatile modifier 
makes the compiler generate the same code, then it would be useless. If 
it forces the compiler to not optimize away accesses to that variable, 
then it can have some use.


 But what appears "obvious" to programmers (even expert experienced 
programmers), and what the standards say, what the compiler does, and 
how it all works on the target in question, can be very different 
things.  When working with bigger cpus with caches and instruction 
re-ordering, for example, "volatile" is not nearly strong enough to give 
you the kind of guarantees we take for granted on avr-gcc.


Yes, I follow LKML too, and all the endless threads on memory ordering / 
volatile / SMP races ;)


This makes as much sense as saying that any volatile is futile, since 
you can compile a program with "-combine -whole-program" and so the 
compiler can always "reason" that any variable will not be accessed 
outside of its control.


No, it's not quite the same.  In particular, if the variable's address 
is known outside the code (for example, if it is given a fixed address, 
such as by the definition of the port I/O registers), then there is no 
way the compiler could make guarantees about the safety of removing the 
"volatile". 


I think you're actually agreeing with me that the compiler can not 
optimize global accesses away, but you're saying that it can for local 
variables because their locations aren't known?


What if the CPU had dedicated storage for the stack frame, and accessing 
locations there had side effects unknown to the compiler?


Yes, I'm grasping at straws here, but the bottom line is: if the side 
effects are unknown to the compiler, _they_ _are_ _unknown_ to the 
compiler. It is best not to assume anything.


Similarly, if different globally accessible functions (such 
as interrupt functions) accessed the variable, it could not remove the 
"volatile".  But for local variables within a function, it is much more 
straightforward to see how such variables could be accessed or addressed.


Well, I could argue that the compiler also knows these functions are 
"interrupt" functions and could assume that any variable modified by 
these functions had to be "treated as volatile", even without the keyword ;)


This would in fact be the best scenario: inside the interrupt functions 
the variables would be accessed as regular variables, but outside they 
would be accessed as volatiles.


Note that I'm not disputing that the compiler could in theory use a 
register instead. I personally don't think that would be a good idea, 
but it might be allowed by the specs. What I'm disputing is that the 
compiler _can not_ ignore the volatile and optimize the loop away 
entirely. That would be a compiler bug, for sure.


It would certainly be a surprise to many (including me) if it *did* 
remove the volatile variable in practice.  But I'm not 100% sure that 
the standards disallow such optimisations - that's all I'm saying.


I hope I'm quoting from the right (currently in use) standard:

"  99. A volatile declaration may be used to describe an object
   corresponding to a memory-mapped input/output port or an
   object  accessed  by  an   asynchronously   interrupting
   function.   Actions  on objects so declared shall not be
   ``optimized out''  by  an  implementation  or  reordered
   except   as  

Re: [avr-gcc-list] Problem with delay loop

2007-10-01 Thread Preston Wilson
"Eric Weddington" wrote:

> ...

> I agree with the statement above that "'volatile' is precisely to warn the
> compiler that it should not 'reason' anything about [the] variable".
> However, David brings up a good point. A local variable is put on the stack,
> generally not the place for hardware to modify the variable. And generally,
> other parts of the program (such as ISRs) don't have access to the specific
> location of the variable on the stack. Both hardware and ISRs work with
> global variables. So *could* a compiler reason that local variables could
> never be volatile? Or are there truly situations where hardware or ISRs
> could modify local variables on the stack?

Yes, ISRs and hardware can modify variables on the stack.

uint8_t *g1;

ISR1()
{
 *g1 = 1;
}

main()
{
  volatile uint8_t v = 0;

  g1 = &v;

  // configure ISRs and enable interrupts
  ... 
}

-Preston




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-10-01 Thread David Brown

Paulo Marques wrote:

David Brown wrote:

[...]
it could perhaps reason that since there is no way for anything 
outside the program to find out where the local volatile variable 
resides, there is no way for anything else to influence or use the 
variable, and therefore the "volatile" qualifier can be ignored.


This sentence makes no sense at all. The "volatile" is precisely to warn 
the compiler that it should not "reason" anything about this variable.




I think the standards are pretty vague regarding exactly what "volatile" 
means.  There is nothing (that I know of) in the standards saying where 
a volatile variable must be allocated.


If you give a volatile qualifier to a local variable, it's obvious that 
you want it to behave differently from regular local variables, so I 
think gcc is doing the best it can, from the weakly defined volatile 
semantics.




It may be obvious to *you*, as the author, that you mean "volatile" to 
work like this.  It certainly works like that on avr-gcc at the moment. 
 But what appears "obvious" to programmers (even expert experienced 
programmers), and what the standards say, what the compiler does, and 
how it all works on the target in question, can be very different 
things.  When working with bigger cpus with caches and instruction 
re-ordering, for example, "volatile" is not nearly strong enough to give 
you the kind of guarantees we take for granted on avr-gcc.


This makes as much sense as saying that any volatile is futile, since 
you can compile a program with "-combine -whole-program" and so the 
compiler can always "reason" that any variable will not be accessed 
outside of its control.




No, it's not quite the same.  In particular, if the variable's address 
is known outside the code (for example, if it is given a fixed address, 
such as by the definition of the port I/O registers), then there is no 
way the compiler could make guarantees about the safety of removing the 
"volatile".  Similarly, if different globally accessible functions (such 
as interrupt functions) accessed the variable, it could not remove the 
"volatile".  But for local variables within a function, it is much more 
straightforward to see how such variables could be accessed or addressed.


Note that I'm not disputing that the compiler could in theory use a 
register instead. I personally don't think that would be a good idea, 
but it might be allowed by the specs. What I'm disputing is that the 
compiler _can not_ ignore the volatile and optimize the loop away 
entirely. That would be a compiler bug, for sure.




It would certainly be a surprise to many (including me) if it *did* 
remove the volatile variable in practice.  But I'm not 100% sure that 
the standards disallow such optimisations - that's all I'm saying.


mvh.,

David


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


RE: [avr-gcc-list] Problem with delay loop

2007-10-01 Thread Eric Weddington


> -Original Message-
> From:
> [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED]
> org] On Behalf Of Paulo Marques
> Sent: Monday, October 01, 2007 7:35 AM
> To: David Brown
> Cc: 'AVR-GCC'
> Subject: Re: [avr-gcc-list] Problem with delay loop
>
> David Brown wrote:
> > [...]
> > it could perhaps reason
> > that since there is no way for anything outside the program
> to find out
> > where the local volatile variable resides, there is no way
> for anything
> > else to influence or use the variable, and therefore the "volatile"
> > qualifier can be ignored.
>
> This sentence makes no sense at all. The "volatile" is
> precisely to warn
> the compiler that it should not "reason" anything about this variable.
>
> If you give a volatile qualifier to a local variable, it's
> obvious that
> you want it to behave differently from regular local variables, so I
> think gcc is doing the best it can, from the weakly defined volatile
> semantics.
>
> This makes as much sense as saying that any volatile is futile, since
> you can compile a program with "-combine -whole-program" and so the
> compiler can always "reason" that any variable will not be accessed
> outside of its control.

There is one other case for a volatile variable, and that is the case of
hardware modifying the variable, which can easily happen in registers. This
is another case of "something outside the program" modifying the variable.

I agree with the statement above that "'volatile' is precisely to warn the
compiler that it should not 'reason' anything about [the] variable".
However, David brings up a good point. A local variable is put on the stack,
generally not the place for hardware to modify the variable. And generally,
other parts of the program (such as ISRs) don't have access to the specific
location of the variable on the stack. Both hardware and ISRs work with
global variables. So *could* a compiler reason that local variables could
never be volatile? Or are there truly situations where hardware or ISRs
could modify local variables on the stack?

Its an interesting question. I'm not sure what the answer is. Perhaps a
language lawyer on comp.lang.c could explain the reasoning behind the
current standard.

Eric Weddington






___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-10-01 Thread Paulo Marques

David Brown wrote:

[...]
it could perhaps reason 
that since there is no way for anything outside the program to find out 
where the local volatile variable resides, there is no way for anything 
else to influence or use the variable, and therefore the "volatile" 
qualifier can be ignored.


This sentence makes no sense at all. The "volatile" is precisely to warn 
the compiler that it should not "reason" anything about this variable.


If you give a volatile qualifier to a local variable, it's obvious that 
you want it to behave differently from regular local variables, so I 
think gcc is doing the best it can, from the weakly defined volatile 
semantics.


This makes as much sense as saying that any volatile is futile, since 
you can compile a program with "-combine -whole-program" and so the 
compiler can always "reason" that any variable will not be accessed 
outside of its control.


Note that I'm not disputing that the compiler could in theory use a 
register instead. I personally don't think that would be a good idea, 
but it might be allowed by the specs. What I'm disputing is that the 
compiler _can not_ ignore the volatile and optimize the loop away 
entirely. That would be a compiler bug, for sure.


--
Paulo Marques
Software Development Department - Grupo PIE, S.A.
Phone: +351 252 290600, Fax: +351 252 290601
Web: www.grupopie.com

"As far as we know, our computer has never had an undetected error."
Weisert


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-10-01 Thread David Brown

Graham Davies wrote:

David Brown wrote (in part):

"... since the local variable is volatile,
it has to be put on the stack."


I don't see how that follows (if it is declared automatic and is of 
local scope).


Graham.



It would be more correct to say that since the local variable is 
volatile, *gcc* puts it on the stack.  As you imply, there is no strict 
requirement that the variable is put in memory anywhere (nor is there 
even a strict requirement that there is a stack at all).  It would be 
perfectly acceptable for the compiler to put such a local volatile 
variable in a register.


I am in fact not entirely convinced that the compiler has to generate 
anything at all here, even with the volatile - it could perhaps reason 
that since there is no way for anything outside the program to find out 
where the local volatile variable resides, there is no way for anything 
else to influence or use the variable, and therefore the "volatile" 
qualifier can be ignored.


mvh.,

David



___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-10-01 Thread Graham Davies

David Brown wrote (in part):

"... since the local variable is volatile,
it has to be put on the stack."


I don't see how that follows (if it is declared automatic and is of local 
scope).


Graham.




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-10-01 Thread David Brown


There are good reasons for much of the stuff produced by the use of 
"volatile" - since the local variable is volatile, it has to be put on 
the stack.  Generating a stack frame on the AVR needs a bit of messing 
around in the prologue and epilogue, including turning off interrupts 
while modifying the stack pointer (blame Atmel for that whoopsie).


What would be really nice is if gcc accepted the concept of "register 
volatile" variables.  I've used them on other compilers in the past to 
get exactly the effect we are looking for here.  But that was in the 
days when "register" was a useful hint to an otherwise fairly poor 
optimiser - gcc, I believe, ignores "register" for local variables.


Slightly better code can be generated with:

void delay2(unsigned int n) {
static volatile unsigned int x;
x = n;
while (x--) ;
}

But even better is:

void delay3(volatile unsigned int n) {
while (n--) {
asm volatile(" " : : );
};
}


mvh.,

David





Royce Pereira wrote:

Hi all,

OK fine I agree.

we have to use 'volatile' and all.

But why must it generate such horrid code...
(I reproduce the comparison again below to get the *real* issue into focus)

The compiler output with the 'correct' code ('volatile' used):
//---
void delay(unsigned int del_cnt)
 {
   2aa: cf 93   pushr28
   2ac: df 93   pushr29
   2ae: cd b7   in  r28, 0x3d   ; 61
   2b0: de b7   in  r29, 0x3e   ; 62
   2b2: 22 97   sbiwr28, 0x02   ; 2
   2b4: 0f b6   in  r0, 0x3f; 63
   2b6: f8 94   cli ;<-disabling interrupts? 
Why?
   2b8: de bf   out 0x3e, r29   ; 62
   2ba: 0f be   out 0x3f, r0; 63
   2bc: cd bf   out 0x3d, r28   ; 61
volatile unsigned int n = del_cnt;
   2be: 9a 83   std Y+2, r25; 0x02
   2c0: 89 83   std Y+1, r24; 0x01
while(n--);
   2c2: 89 81   ldd r24, Y+1; 0x01
   2c4: 9a 81   ldd r25, Y+2; 0x02
   2c6: 01 97   sbiwr24, 0x01   ; 1
   2c8: 9a 83   std Y+2, r25; 0x02
   2ca: 89 83   std Y+1, r24; 0x01
   2cc: 89 81   ldd r24, Y+1; 0x01
   2ce: 9a 81   ldd r25, Y+2; 0x02
   2d0: 8f 5f   subir24, 0xFF   ; 255
   2d2: 9f 4f   sbcir25, 0xFF   ; 255
   2d4: b1 f7   brne.-20; 0x2c2 
   2d6: 22 96   adiwr28, 0x02   ; 2
   2d8: 0f b6   in  r0, 0x3f; 63
   2da: f8 94   cli
   2dc: de bf   out 0x3e, r29   ; 62
   2de: 0f be   out 0x3f, r0; 63
   2e0: cd bf   out 0x3d, r28   ; 61
   2e2: df 91   pop r29
   2e4: cf 91   pop r28
   2e6: 08 95   ret

return;
 }
//===

Output of the older -WinAVR-20060421-version (with the alleged 'wrong' C code)

//==
void delay(word cnt)
{
   while(cnt--);
  286:  01 97   sbiwr24, 0x01   ; 1
  288:  2f ef   ldi r18, 0xFF   ; 255
  28a:  8f 3f   cpi r24, 0xFF   ; 255
  28c:  92 07   cpc r25, r18
  28e:  d9 f7   brne.-10; 0x286 
  290:  08 95   ret
 return;
}
//===



So which is the right output we want? Obviously the second.

Agreed not using 'volatile' optimises the code to a mere 'ret'. I'm ok with 
that.

But should'nt the 'correct' code produce the same output (the shorter version 
above)??

Thanks,

--Royce.







___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread David Kelly


On Sep 28, 2007, at 8:58 PM, Graham Davies wrote:


David Kelly wrote:

... because it was volatile it *had* to
be fetched and stored each time.


Oh boy.  That's a really interesting statement (to me anyway, but I  
have a volatile fetish).  You're saying that having chosen to put  
the variable in memory, the compiler is obliged to fetch it prior  
to and store it after each increment.  I can't disagree with that.   
But, does it explain the "horrid code"?  Does the compiler *have*  
to put the variable in memory?


I guess it doesn't really have to if it can assure that the variable  
has not been passed by address reference to another routine such as  
an interrupt. Thats pretty much the definition of volatile in the  
first place, that one is telling the compiler that it can be changed  
somewhere somehow outside of the compiler's control.


  It is declared as an automatic variable, right?  That means that  
the compiler has complete freedom in deciding where to put it and a  
register is a perfectly good choice.  The scope is local, so the  
variable can't be accessed outside the function.


It could be passed to another function by address.

  It isn't static, so its value isn't preserved when execution  
leaves the function.  Is there a body of opinion that the volatile  
modifier obliges the compiler to put a variable in memory?  I'm  
just interested.  If this is too off-topic, feel free to ignore  
me.  Actually, feel free to ignore me at any time.


I think there is room for other variations on "volatile" as much of  
what Graham says applies nicely in interrupt service routines. No  
need to treat most application volatile variables with kid gloves  
when interrupts are masked. Many variables mapped to a peripheral  
device needs volatile no matter what. Not for an ouput port, but an  
input port for sure, and hardware timers, etc. But not for my example  
software timer, at least not in the interrupt routine where it gets  
decremented:


if( timer_serial_cmd )
timer_serial_cmd--;

timer_serial_cmd above only needs to be volatile outside of the  
interrupt routine.


It is a stretch to say that any code intended to cause a deliberate  
delay is horrible. The code provided in  is about  
as painless as anything can be, no matter that it is assembly in a C  
function wrapper.


I wrote earlier, if an Output Compare is not being used elsewhere,  
they make excellent delay timers without tying up the CPU in a busy  
loop. My example tied the CPU up, but thats not the way I generally  
use them. Software timers implemented in my tick interrupt for longer  
events, OCR's for precise short periods, and more complex use of the  
OCR hardware for repetitive events such as PWM motor control.


--
David Kelly N4HHE, [EMAIL PROTECTED]

Whom computers would destroy, they must first drive mad.





___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread Graham Davies

David Kelly wrote:

... because it was volatile it *had* to
be fetched and stored each time.


Oh boy.  That's a really interesting statement (to me anyway, but I have a 
volatile fetish).  You're saying that having chosen to put the variable in 
memory, the compiler is obliged to fetch it prior to and store it after each 
increment.  I can't disagree with that.  But, does it explain the "horrid 
code"?  Does the compiler *have* to put the variable in memory?  It is 
declared as an automatic variable, right?  That means that the compiler has 
complete freedom in deciding where to put it and a register is a perfectly 
good choice.  The scope is local, so the variable can't be accessed outside 
the function.  It isn't static, so its value isn't preserved when execution 
leaves the function.  Is there a body of opinion that the volatile modifier 
obliges the compiler to put a variable in memory?  I'm just interested.  If 
this is too off-topic, feel free to ignore me.  Actually, feel free to 
ignore me at any time.


Graham.




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread David Kelly
On Fri, Sep 28, 2007 at 11:26:43PM +0530, Royce Pereira wrote:
> Hi all,
> 
> OK fine I agree.
> 
> we have to use 'volatile' and all.
> 
> But why must it generate such horrid code...

There are those here who would tell you that any calibrated delay loop
is horrible code.

The stack has to be protected when space is being allocated, believe
this is normal for any auto variable allocation because the registers
being used to offset the stack are the same the runtime will use to
process an interrupt. Notice the SREG is restored in the middle of
updating the stack pointer? This is because the next instruction is
already in the pipe and can't be interrupted.

Make it "static volatile" for simpler code. The other was nasty because
it had to access stack-relative, and because it was volatile it *had* to
be fetched and stored each time.

void delay_loop(unsigned int delay)
{
  ba:   90 93 01 01 sts 0x0101, r25
  be:   80 93 00 01 sts 0x0100, r24
static volatile unsigned int vdelay;

vdelay = delay;
while( vdelay-- )
  c2:   80 91 00 01 lds r24, 0x0100
  c6:   90 91 01 01 lds r25, 0x0101
  ca:   01 97   sbiwr24, 0x01   ; 1
  cc:   90 93 01 01 sts 0x0101, r25
  d0:   80 93 00 01 sts 0x0100, r24
  d4:   80 91 00 01 lds r24, 0x0100
  d8:   90 91 01 01 lds r25, 0x0101
  dc:   8f 5f   subir24, 0xFF   ; 255
  de:   9f 4f   sbcir25, 0xFF   ; 255
  e0:   81 f7   brne.-32; 0xc2 
  e2:   08 95   ret

-- 
David Kelly N4HHE, [EMAIL PROTECTED]

Whom computers would destroy, they must first drive mad.


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread Royce Pereira
Hi all,

OK fine I agree.

we have to use 'volatile' and all.

But why must it generate such horrid code...
(I reproduce the comparison again below to get the *real* issue into focus)

The compiler output with the 'correct' code ('volatile' used):
//---
void delay(unsigned int del_cnt)
 {
   2aa: cf 93   pushr28
   2ac: df 93   pushr29
   2ae: cd b7   in  r28, 0x3d   ; 61
   2b0: de b7   in  r29, 0x3e   ; 62
   2b2: 22 97   sbiwr28, 0x02   ; 2
   2b4: 0f b6   in  r0, 0x3f; 63
   2b6: f8 94   cli ;<-disabling interrupts? 
Why?
   2b8: de bf   out 0x3e, r29   ; 62
   2ba: 0f be   out 0x3f, r0; 63
   2bc: cd bf   out 0x3d, r28   ; 61
volatile unsigned int n = del_cnt;
   2be: 9a 83   std Y+2, r25; 0x02
   2c0: 89 83   std Y+1, r24; 0x01
while(n--);
   2c2: 89 81   ldd r24, Y+1; 0x01
   2c4: 9a 81   ldd r25, Y+2; 0x02
   2c6: 01 97   sbiwr24, 0x01   ; 1
   2c8: 9a 83   std Y+2, r25; 0x02
   2ca: 89 83   std Y+1, r24; 0x01
   2cc: 89 81   ldd r24, Y+1; 0x01
   2ce: 9a 81   ldd r25, Y+2; 0x02
   2d0: 8f 5f   subir24, 0xFF   ; 255
   2d2: 9f 4f   sbcir25, 0xFF   ; 255
   2d4: b1 f7   brne.-20; 0x2c2 
   2d6: 22 96   adiwr28, 0x02   ; 2
   2d8: 0f b6   in  r0, 0x3f; 63
   2da: f8 94   cli
   2dc: de bf   out 0x3e, r29   ; 62
   2de: 0f be   out 0x3f, r0; 63
   2e0: cd bf   out 0x3d, r28   ; 61
   2e2: df 91   pop r29
   2e4: cf 91   pop r28
   2e6: 08 95   ret

return;
 }
//===

Output of the older -WinAVR-20060421-version (with the alleged 'wrong' C code)
>> //==
>> void delay(word cnt)
>> {
>>while(cnt--);
>>   286:   01 97   sbiwr24, 0x01   ; 1
>>   288:   2f ef   ldi r18, 0xFF   ; 255
>>   28a:   8f 3f   cpi r24, 0xFF   ; 255
>>   28c:   92 07   cpc r25, r18
>>   28e:   d9 f7   brne.-10; 0x286 
>>   290:   08 95   ret
>>  return;
>> }
>> //===
>>

So which is the right output we want? Obviously the second.

Agreed not using 'volatile' optimises the code to a mere 'ret'. I'm ok with 
that.

But should'nt the 'correct' code produce the same output (the shorter version 
above)??

Thanks,

--Royce.



-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


RE: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread Dave Hansen

> Date: Fri, 28 Sep 2007 14:21:38 +0530> To: [EMAIL PROTECTED]> Subject: Re: 
> [avr-gcc-list] Problem with delay loop> From: [EMAIL PROTECTED]> CC: 
> AVR-GCC-list@nongnu.org> > Hi,> > On Fri, 28 Sep 2007 13:42:18 +0530, Klaus 
> Rudolph <[EMAIL PROTECTED]> wrote:> > > The code has been optimized. Well 
> done!> > If you need the variable access use 'volatile'> >> Why does it get 
> optimised?
 
Because it is allowed, and gcc is sophisticated enough to do so.
> I understand the meaning of 'volatile', but why is it required here ?
 
What is the meaning of volatile?  Hint: it has nothing to do with "sharing."
> It is clear that the variable is changing in the code itself (not outside it).
 
Precisely.  The optimizer recognized that neither the intermediate values nor 
even the final value of the variable had any effect on the outcome of the 
program, and therefore removed the calculation of those values from the code.
> > Again- it worked in the older avr-gcc. Was that a bug(the fact that it 
> > worked)?
 
No.  It was a missed opportunity for optimization.  The program produced the 
same result, it just took longer to do so.
 
Again, you would do well to investigate the library's delay.h header and the 
facilities it provides.  These work very well.
 
HTH,
 
   -=Dave
 
_
Explore the seven wonders of the world
http://search.msn.com/results.aspx?q=7+wonders+world&mkt=en-US&form=QBRE___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread David Kelly
On Fri, Sep 28, 2007 at 09:05:40AM -0500, David Kelly wrote:
> 
> For finer delays don't forget the OCR functions on the timers. Is pretty
> easy to write and create very accurate delays with:
> 
> void delay( uint8_t delay );
> {
>   OCR2A = TCNT2 + delay;
>   TIFR2 = (1< 
>   //  wait until TCNT2 matches OCR2A
>   while( ( TIFR2 && (1<   ;
> }

Above should be while( ( TIFR2 & (1

Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread David Kelly
On Fri, Sep 28, 2007 at 01:29:19PM +0530, Royce Pereira wrote:
> Hi all,
> 
> In the latest WinAVR (avr-gcc (GCC) 4.1.2 (WinAVR 20070525) I found this.
> 
> Check this out:
> //==
> void delay(unsigned del_cnt)
> {
>while(del_cnt--);
> 
>return;
> }
> //===

I agree with what others have said, no matter the old compiler did what
you intended with the above code, the code is less that fully correct.
Is legal for the compiler to burn cycles in the loop, is legal for the
compiler to recognize a do-nothing loop and remove it. You are not the
first to discover this that is why the volatile modifier exists.

Why are you not using hardware timers? First thing I do on a new project
is set up a hardware timer to tick away at 60 or 100 Hz or something
close. Then in the interrupt routine I commonly create "software timers"
something like this:

if( timer_serial_cmd )
timer_serial_cmd--;

Elsewhere in my code I might start receiving a serial command string
where no two characters should arrive more than 100 ms apart. At 60 Hz
that would be 6 ticks, 10 at 100 Hz. So I put 6 or 10 in
timer_serial_cmd and if ever I find timer_serial_cmd to be zero I know
too much time has passed.

Notice timer_serial_cmd needs to be volatile but you might get away
without. I use uint8_t more than anything else as my variable type. If
your timer_serial_cmd is 16 bits then if it is not zero interrupts need
to be locked out while it is initialized. Or a quick and dirty way is to
write the value twice knowing the 60 Hz interrupt isn't going to fire
twice in 2 lines of code:

volatile uint16_t timer_serial_cmd;

timer_serial_cmd = 1000;
timer_serial_cmd = 1000;

or
cli();
timer_serial_cmd = 1000;
sei();

For finer delays don't forget the OCR functions on the timers. Is pretty
easy to write and create very accurate delays with:

void delay( uint8_t delay );
{
OCR2A = TCNT2 + delay;
TIFR2 = (1

RE: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread Eric Weddington


> -Original Message-
> From:
> [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED]
> org] On Behalf Of David Brown
> Sent: Friday, September 28, 2007 3:17 AM
> To: AVR-GCC
> Subject: Re: [avr-gcc-list] Problem with delay loop
>
>
> This is probably in the FAQ somewhere - if not, it should be!

I checked the avr-libc docs, and it's not in the FAQ strangely enough. It's
asked so often, it should be #2.

Would someone be willing to write up some text and submit it to the Patch
Tracker on the avr-libc project? We'll make sure that it gets in the docs
for the next release.

Thanks
Eric Weddington




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread Klaus Rudolph

I think we are discussing not the solution :-)

The compiler optimizes unused code away, that is OK!
If we use a volatile, the WRITE ACCESS could not longer be optimized and 
also a new READ ACCESS before subtraction must! be done. That is what 
the compiler do, that is also OK!
If there is a "local" volatile variable, the compiler build a new stack 
frame which results in a big prologue and epilogue for the function, 
which is OK!


The solution to have a time consumtion function is to use the library!
Sorry that the volatile hack is not what you need. But it burnes time as 
expected :-) and nothing else is requested. If you need a handcafted 
delay loop use inline assembler instead. The behaviour of the compiler 
can change from version to version. And I hope it will change a lot to 
get better code!


Bye
 Klaus



Royce Pereira wrote:

So I have to write more 'C' code :) to get the same
stuff done, in the 'new & smarter' compiler!


Not more code, just correct code.

Have you tried returning the final value of your delay argument from the 
function?  If the compiler optimizes only within the boundaries of 
individual functions it won't be able to take advantage of the fact that 
the result is not used.  Strictly, this isn't correct either as the 
compiler could just assign zero and return.  But, it may not be smart 
enough to do that and you may get closer to your original assembly 
language.  Another way to go would be to write the function directly in 
assembly language.


Graham.




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list





___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread Graham Davies

Royce Pereira wrote:

So I have to write more 'C' code :) to get the same
stuff done, in the 'new & smarter' compiler!


Not more code, just correct code.

Have you tried returning the final value of your delay argument from the 
function?  If the compiler optimizes only within the boundaries of 
individual functions it won't be able to take advantage of the fact that the 
result is not used.  Strictly, this isn't correct either as the compiler 
could just assign zero and return.  But, it may not be smart enough to do 
that and you may get closer to your original assembly language.  Another way 
to go would be to write the function directly in assembly language.


Graham.




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread Royce Pereira
Hi Klaus,
On Fri, 28 Sep 2007 14:57:14 +0530, Klaus Rudolph <[EMAIL PROTECTED]> wrote:

> Please use optimizer! Something like -O2 -O3 -Os ... as you need!

My makefile already has
OPT = s

>
> Simplify your delay loop:
> void delay(volatile word cnt) { ...
>
Already tried that. No change.

If it's worked for you with whatever you have suggested, could you paste a 
snippet of your output ? Thanks!

regards,

--Royce.




-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread Klaus Rudolph

Please use optimizer! Something like -O2 -O3 -Os ... as you need!

Simplify your delay loop:
void delay(volatile word cnt) { ...

Have fun!


Royce Pereira schrieb:

Hi,

On Fri, 28 Sep 2007 14:47:26 +0530, David Brown <[EMAIL PROTECTED]> wrote:


This is probably in the FAQ somewhere - if not, it should be!

The compiler is smart enough to figure out that your delay function does
no useful work - thus the optimiser does not generate any code.  This is
correct compilation - it's your code that is wrong.  The difference is
that the newer version of the compiler is smarter than the older version
(or newer makefiles have higher optimisation enabled by default).

The correct way to write such a loop is:

void delay(unsigned int del_cnt) {
volatile unsigned int n = del_cnt;
while (n--);
}


I tried that and -Yikes !! Here's what I get :( :
Compare it to the short & sweet loop of the earlier avr-gcc version (below)...
//---
void delay(unsigned int del_cnt)
{
  2aa:  cf 93   pushr28
  2ac:  df 93   pushr29
  2ae:  cd b7   in  r28, 0x3d   ; 61
  2b0:  de b7   in  r29, 0x3e   ; 62
  2b2:  22 97   sbiwr28, 0x02   ; 2
  2b4:  0f b6   in  r0, 0x3f; 63
  2b6:  f8 94   cli
  2b8:  de bf   out 0x3e, r29   ; 62
  2ba:  0f be   out 0x3f, r0; 63
  2bc:  cd bf   out 0x3d, r28   ; 61
   volatile unsigned int n = del_cnt;
  2be:  9a 83   std Y+2, r25; 0x02
  2c0:  89 83   std Y+1, r24; 0x01
   while(n--);
  2c2:  89 81   ldd r24, Y+1; 0x01
  2c4:  9a 81   ldd r25, Y+2; 0x02
  2c6:  01 97   sbiwr24, 0x01   ; 1
  2c8:  9a 83   std Y+2, r25; 0x02
  2ca:  89 83   std Y+1, r24; 0x01
  2cc:  89 81   ldd r24, Y+1; 0x01
  2ce:  9a 81   ldd r25, Y+2; 0x02
  2d0:  8f 5f   subir24, 0xFF   ; 255
  2d2:  9f 4f   sbcir25, 0xFF   ; 255
  2d4:  b1 f7   brne.-20; 0x2c2 
  2d6:  22 96   adiwr28, 0x02   ; 2
  2d8:  0f b6   in  r0, 0x3f; 63
  2da:  f8 94   cli
  2dc:  de bf   out 0x3e, r29   ; 62
  2de:  0f be   out 0x3f, r0; 63
  2e0:  cd bf   out 0x3d, r28   ; 61
  2e2:  df 91   pop r29
  2e4:  cf 91   pop r28
  2e6:  08 95   ret

02e8 :

   return;
}
//===

Output of the older -WinAVR-20060421-version (and without the 'volatile' thingy 
too!)

//==
void delay(word cnt)
{
   while(cnt--);
  286:  01 97   sbiwr24, 0x01   ; 1
  288:  2f ef   ldi r18, 0xFF   ; 255
  28a:  8f 3f   cpi r24, 0xFF   ; 255
  28c:  92 07   cpc r25, r18
  28e:  d9 f7   brne.-10; 0x286 
  290:  08 95   ret


   return;
}
//===



Thanks,

--Royce.




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread Royce Pereira
Hi,

On Fri, 28 Sep 2007 14:47:26 +0530, David Brown <[EMAIL PROTECTED]> wrote:

>
> This is probably in the FAQ somewhere - if not, it should be!
>
> The compiler is smart enough to figure out that your delay function does
> no useful work - thus the optimiser does not generate any code.  This is
> correct compilation - it's your code that is wrong.  The difference is
> that the newer version of the compiler is smarter than the older version
> (or newer makefiles have higher optimisation enabled by default).
>
> The correct way to write such a loop is:
>
> void delay(unsigned int del_cnt) {
>   volatile unsigned int n = del_cnt;
>   while (n--);
> }

I tried that and -Yikes !! Here's what I get :( :
Compare it to the short & sweet loop of the earlier avr-gcc version (below)...
//---
void delay(unsigned int del_cnt)
{
  2aa:  cf 93   pushr28
  2ac:  df 93   pushr29
  2ae:  cd b7   in  r28, 0x3d   ; 61
  2b0:  de b7   in  r29, 0x3e   ; 62
  2b2:  22 97   sbiwr28, 0x02   ; 2
  2b4:  0f b6   in  r0, 0x3f; 63
  2b6:  f8 94   cli
  2b8:  de bf   out 0x3e, r29   ; 62
  2ba:  0f be   out 0x3f, r0; 63
  2bc:  cd bf   out 0x3d, r28   ; 61
   volatile unsigned int n = del_cnt;
  2be:  9a 83   std Y+2, r25; 0x02
  2c0:  89 83   std Y+1, r24; 0x01
   while(n--);
  2c2:  89 81   ldd r24, Y+1; 0x01
  2c4:  9a 81   ldd r25, Y+2; 0x02
  2c6:  01 97   sbiwr24, 0x01   ; 1
  2c8:  9a 83   std Y+2, r25; 0x02
  2ca:  89 83   std Y+1, r24; 0x01
  2cc:  89 81   ldd r24, Y+1; 0x01
  2ce:  9a 81   ldd r25, Y+2; 0x02
  2d0:  8f 5f   subir24, 0xFF   ; 255
  2d2:  9f 4f   sbcir25, 0xFF   ; 255
  2d4:  b1 f7   brne.-20; 0x2c2 
  2d6:  22 96   adiwr28, 0x02   ; 2
  2d8:  0f b6   in  r0, 0x3f; 63
  2da:  f8 94   cli
  2dc:  de bf   out 0x3e, r29   ; 62
  2de:  0f be   out 0x3f, r0; 63
  2e0:  cd bf   out 0x3d, r28   ; 61
  2e2:  df 91   pop r29
  2e4:  cf 91   pop r28
  2e6:  08 95   ret

02e8 :

   return;
}
//===

Output of the older -WinAVR-20060421-version (and without the 'volatile' thingy 
too!)
>> //==
>> void delay(word cnt)
>> {
>>while(cnt--);
>>   286:   01 97   sbiwr24, 0x01   ; 1
>>   288:   2f ef   ldi r18, 0xFF   ; 255
>>   28a:   8f 3f   cpi r24, 0xFF   ; 255
>>   28c:   92 07   cpc r25, r18
>>   28e:   d9 f7   brne.-10; 0x286 
>>   290:   08 95   ret
>>
>>
>>return;
>> }
>> //===
>>

Thanks,

--Royce.
-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread Royce Pereira
Hi,
On Fri, 28 Sep 2007 14:47:26 +0530, David Brown <[EMAIL PROTECTED]> wrote:

>
> This is probably in the FAQ somewhere - if not, it should be!
>
> The compiler is smart enough to figure out that your delay function does
> no useful work - thus the optimiser does not generate any code.  This is
> correct compilation - it's your code that is wrong.  The difference is
> that the newer version of the compiler is smarter than the older version
> (or newer makefiles have higher optimisation enabled by default).
>
> The correct way to write such a loop is:
>
> void delay(unsigned int del_cnt) {
>   volatile unsigned int n = del_cnt;
>   while (n--);
> }

So I have to write more 'C' code :) to get the same stuff done, in the 'new & 
smarter' compiler! Interesting.

Doesn't seem right, some how.

Regards,
--Royce.

> mvh.,
>
> David
>
>
> Royce Pereira wrote:
>> Hi all,
>>
>> In the latest WinAVR (avr-gcc (GCC) 4.1.2 (WinAVR 20070525) I found this.
>>
>> Check this out:
>> //==
>> void delay(unsigned del_cnt)
>> {
>>while(del_cnt--);
>>
>>return;
>> }
>> //===
>>
>> Compiles as (from the .lss file):
>>
>> //===
>> void delay(word cnt)
>> {
>>   2aa:   08 95   ret
>>
>>while(cnt--);
>>
>>return;
>> }
>> //===
>>
>> The loop is not executed !!
>>
>> Where as in an older version (WinAVR-20060421)
>>
>> It compiles correctly as:
>> //==
>> void delay(word cnt)
>> {
>>while(cnt--);
>>   286:   01 97   sbiwr24, 0x01   ; 1
>>   288:   2f ef   ldi r18, 0xFF   ; 255
>>   28a:   8f 3f   cpi r24, 0xFF   ; 255
>>   28c:   92 07   cpc r25, r18
>>   28e:   d9 f7   brne.-10; 0x286 
>>   290:   08 95   ret
>>
>>
>>return;
>> }
>> //===
>>
>> As a result none of my delays used in my older programs work when 
>> recompiled...
>>
>> Thanks,
>>
>> --Royce
>>
>
>
>
> ___
> AVR-GCC-list mailing list
> AVR-GCC-list@nongnu.org
> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
>



-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread David Brown


This is probably in the FAQ somewhere - if not, it should be!

The compiler is smart enough to figure out that your delay function does 
no useful work - thus the optimiser does not generate any code.  This is 
correct compilation - it's your code that is wrong.  The difference is 
that the newer version of the compiler is smarter than the older version 
(or newer makefiles have higher optimisation enabled by default).


The correct way to write such a loop is:

void delay(unsigned int del_cnt) {
volatile unsigned int n = del_cnt;
while (n--);
}

(Incidentally, *never* use "unsigned" as a shorthand - write the proper 
type name "unsigned int".  The same applies to "long", "short", 
"signed", etc.)


If you don't know how to use "volatile", there should be plenty of 
references on the web (including the archives for this mailing list), 
which will give you a better explanation.


mvh.,

David


Royce Pereira wrote:

Hi all,

In the latest WinAVR (avr-gcc (GCC) 4.1.2 (WinAVR 20070525) I found this.

Check this out:
//==
void delay(unsigned del_cnt)
{
   while(del_cnt--);

   return;
}
//===

Compiles as (from the .lss file):

//===
void delay(word cnt)
{
  2aa:  08 95   ret

   while(cnt--);

   return;
}
//===

The loop is not executed !!

Where as in an older version (WinAVR-20060421)

It compiles correctly as:
//==
void delay(word cnt)
{
   while(cnt--);
  286:  01 97   sbiwr24, 0x01   ; 1
  288:  2f ef   ldi r18, 0xFF   ; 255
  28a:  8f 3f   cpi r24, 0xFF   ; 255
  28c:  92 07   cpc r25, r18
  28e:  d9 f7   brne.-10; 0x286 
  290:  08 95   ret


   return;
}
//===

As a result none of my delays used in my older programs work when recompiled...

Thanks,

--Royce





___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread Royce Pereira
Hi,

On Fri, 28 Sep 2007 13:42:18 +0530, Klaus Rudolph <[EMAIL PROTECTED]> wrote:

> The code has been optimized. Well done!
> If you need the variable access use 'volatile'
>
Why does it get optimised?
I understand the meaning of 'volatile', but why is it required here ?
It is clear that the variable is changing in the code itself (not outside it).

Again- it worked in the older avr-gcc. Was that a bug(the fact that it worked)?

even rewriting it as:
//
void delay(unsigned cnt)
{
   while(cnt)
   cnt--;
}   
//
does not work. (Why not ?)

Thanks,

--Royce.

>> Hi all,
>>
>> In the latest WinAVR (avr-gcc (GCC) 4.1.2 (WinAVR 20070525) I found this.
>>
>> Check this out:
>> //==
>> void delay(unsigned del_cnt)
>> {
>>while(del_cnt--);
>>
>>return;
>> }
>> //===
>>
>> Compiles as (from the .lss file):
>>
>> //===
>> void delay(word cnt)
>> {
>>   2aa:   08 95   ret
>>
>>while(cnt--);
>>
>>return;
>> }
>> //===
>>
>> The loop is not executed !!
>>
>> Where as in an older version (WinAVR-20060421)
>>
>> It compiles correctly as:
>> //==
>> void delay(word cnt)
>> {
>>while(cnt--);
>>   286:   01 97   sbiwr24, 0x01   ; 1
>>   288:   2f ef   ldi r18, 0xFF   ; 255
>>   28a:   8f 3f   cpi r24, 0xFF   ; 255
>>   28c:   92 07   cpc r25, r18
>>   28e:   d9 f7   brne.-10; 0x286 
>>   290:   08 95   ret
>>
>>
>>return;
>> }
>> //===
>>
>>
>>
>> 
>>
>> ___
>> AVR-GCC-list mailing list
>> AVR-GCC-list@nongnu.org
>> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
>
>



-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread Klaus Rudolph

The code has been optimized. Well done!
If you need the variable access use 'volatile'


Hi all,

In the latest WinAVR (avr-gcc (GCC) 4.1.2 (WinAVR 20070525) I found this.

Check this out:
//==
void delay(unsigned del_cnt)
{
   while(del_cnt--);

   return;
}
//===

Compiles as (from the .lss file):

//===
void delay(word cnt)
{
  2aa:  08 95   ret

   while(cnt--);

   return;
}
//===

The loop is not executed !!

Where as in an older version (WinAVR-20060421)

It compiles correctly as:
//==
void delay(word cnt)
{
   while(cnt--);
  286:  01 97   sbiwr24, 0x01   ; 1
  288:  2f ef   ldi r18, 0xFF   ; 255
  28a:  8f 3f   cpi r24, 0xFF   ; 255
  28c:  92 07   cpc r25, r18
  28e:  d9 f7   brne.-10; 0x286 
  290:  08 95   ret


   return;
}
//===





___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list




___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


Re: [avr-gcc-list] Problem with delay loop

2007-09-28 Thread Wouter van Gulik

Royce Pereira schreef:

Hi all,

In the latest WinAVR (avr-gcc (GCC) 4.1.2 (WinAVR 20070525) I found this.

Check this out:
//==
void delay(unsigned del_cnt)
{
   while(del_cnt--);

   return;
}
//===



Well writing your own delay_loops is not recommended, because the 
optimiser might optimise your loop away. Use  instead.


Please note that delay.h might not work if compiling without optimiser 
(but then again, your loop will not be gone)


HTH,

Wouter


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list


[avr-gcc-list] Problem with delay loop

2007-09-28 Thread Royce Pereira
Hi all,

In the latest WinAVR (avr-gcc (GCC) 4.1.2 (WinAVR 20070525) I found this.

Check this out:
//==
void delay(unsigned del_cnt)
{
   while(del_cnt--);

   return;
}
//===

Compiles as (from the .lss file):

//===
void delay(word cnt)
{
  2aa:  08 95   ret

   while(cnt--);

   return;
}
//===

The loop is not executed !!

Where as in an older version (WinAVR-20060421)

It compiles correctly as:
//==
void delay(word cnt)
{
   while(cnt--);
  286:  01 97   sbiwr24, 0x01   ; 1
  288:  2f ef   ldi r18, 0xFF   ; 255
  28a:  8f 3f   cpi r24, 0xFF   ; 255
  28c:  92 07   cpc r25, r18
  28e:  d9 f7   brne.-10; 0x286 
  290:  08 95   ret


   return;
}
//===

As a result none of my delays used in my older programs work when recompiled...

Thanks,

--Royce

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/


___
AVR-GCC-list mailing list
AVR-GCC-list@nongnu.org
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list