This is the mail archive of the crossgcc@sourceware.cygnus.com mailing list for the crossgcc project.

See the CrossGCC FAQ for lots more infromation.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: gcc volatile behaviour


   From: Zoltan Kocsi <zoltan@bendor.com.au>
   Date: Sat,  9 Oct 1999 22:56:12 +1000 (EST)

   When the value of an assignment expression where the left-hand side is 
   volatile is used, gcc re-fetches the left-hand object. That is:

     volatile int a, b;
     a = b = 0;

   compiles to

	   clr.l b
	   move.l b,%d0
	   move.l %d0,a

   Apart from the fact that the involvement of d0 is not really a
   necessity (with -O3), I do not understand why does it fetch 'b' ?

In C, assignment is a right associative operator, and its value is the
value of the variable to which the assignment is made.  The statement
    a = b = 0;
is equivalent to
    a = (b = 0);
which is equivalent to
    b = 0;
    a = b;
When b is volatile, gcc must reflect both the store to b and the load
from b.

   Similarly, when one does stringcopy:

      strcpy( char *a char *b )
      {
	while( *a++ = *b++ );
      }

   compiles the loop to the inefficient but correct

   .L7:
	   move.b (%a0)+,%d0
	   move.b %d0,(%a1)+
	   jbne .L7

   Changing the declaration of 'a' to volatile char *a, the result is this:

   .L7:
	   move.b (%a1)+,(%a0)
	   move.b (%a0)+,%d0
	   jbne .L7

   This means that the copy is not terminated when the '\0' is *written*
   to the area pointed by 'a' but when a zero is *read back* from the given 
   area. In case of HW buffers this may not be what the programmer had in 
   mind, for buffers sometimes are write only, for example.

Again, the test of the result of an assignment implies reading the
result from the variable.  That follows from the definition of the C
assignment operator.

Actually, volatile isn't defined all that well in C.  If you need
control over memory locations, use very simple constructions and spell
out each step.  Write
    b = 0;
    a = 0;
or
    while (true) {
      char c = *b++;
      *a++ = c;
      if (c == 0)
        break;
    }
Then you will have a better idea as to what instruction sequence you
will get.

Ian

------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sourceware.cygnus.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]