cire@CISCO.COM (cire|eric) (03/13/89)
That is the menace. Consider the fragment listed below. The struct foo1 is used to point at a descriptor of an i/o device. Now I've noticed two points: 1) When the statement "c = *ptr->data" actually does retrieve the data the assembly code "moveb a0@(1),d1" is used. "c" is an unsigned char. Now this is certainly correct of the compiler to generate this because the statement is being looked at as "c = (uchar) (*ptr->data)". However, the desired intent is go get the volatile short *ptr->data and then cast it to be an unsigned char. I haven't seen the ANSI spec but my interpretation of volatile was simply refetch this cell every time you use it. It strikes me that it would be better if it were something like refetch this unsigned short everytime you need it. 2) I've also noticed that the optimizer removes any references for cells that are not used. When the fragment is compiled with -O the reference at "A" below only remains because of the call to forceuse. The reference at "B" disappears. For this fragment this behaviour causes havoc. The intent at "B" is to clear out a byte stream coming from the device but the data register is never accessed. This is a common use of volatile. For larger fragments of code whether or not the reference is around is dependent on how the compiler views the code. This can result in some very entertaining results. Strikes me that perhaps the meaning of volatile should be always fetch the cell as the defined type no matter what. Thoughts? -c cire|eric Eric B. Decker cisco Systems Menlo Park, California email: cire@cisco.com uSnail: 1360 Willow Rd., Menlo Park, CA 94025 Phone : (415) 326-1941 ------------------------------------------------------------------------ test.c: typedef struct foo1 { volatile unsigned short *data; volatile unsigned short *status; } footype; void forceuse(c) unsigned char c; { int blah; blah = c; } void test (ptr) footype *ptr; { register unsigned int status; register int flag; register unsigned char c=0; while ((status = *ptr->status) & 1) { c = *ptr->data; /* <- A */ if (status & 128) { while (*ptr->status & 1) c = *ptr->data; /* <- B */ c = 0; } } forceuse(c); } int main() { unsigned char buff[1024]; footype blah; blah.data=(unsigned short *) &buff[0]; blah.status=(unsigned short *) &buff[2]; buff[3]=1; buff[0]=0xAA; buff[1]=0x55; (void) test(&blah); } ------------------------------------------------------------------------ compiling: gcc -v -S -O -W test.c -o test_opt.s gcc version 1.32 /usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -D__OPTIMIZE__ -D__HAVE_68881__ -Dmc68020 test.c /tmp/cca16995.cpp GNU CPP version 1.32 /usr/local/lib/gcc-cc1 /tmp/cca16995.cpp -quiet -dumpbase test.c -O -W -version -o test_opt.s GNU C version 1.32 (68k, MIT syntax) compiled by GNU C version 1.32. ------------------------------------------------------------------------ test_opt.s: .globl _test _test: link a6,#0 moveml #0x2020,sp@- movel a6@(8),a1 clrb d1 movel a1@(4),a2 clrl d2 jra L3 L9: movel a1@,a0 <- fetch data, only here because of forceuse moveb a0@(1),d1 <- tstb d2 jge L3 movel a1@(4),a0 L6: movew a0@,d0 btst #0,d0 jne L6 <- should be a reference to data here! clrb d1 L3: movew a2@,d0 movew d0,d2 btst #0,d2 jne L9 clrl d0 moveb d1,d0 movel d0,sp@- jbsr _forceuse moveml a6@(-8),#0x404 unlk a6 rts
brooks@vette.llnl.gov (Eugene Brooks) (03/14/89)
In article <8903130045.AA21334@prep.ai.mit.edu> cire@CISCO.COM (cire|eric)
writes a description of a problem involving a reference to a volatile int
which is cast to an unsigned char. I hope that the intent of the ANSI
volatile usage is that the int gets picked up as an int and then is cast
to a unsigned char by truncation. A volatile int is a volatile int, not
a place to pick up a volatile char! Does anyone know what the standard
really means in the area?
I would hope, in addition, that the volatile attributes of a reference
are available (in GCC) to the back end at the machine description level. On
shared memory multiprocessor systems which use explicitly managed caches one
has to use an alternate load instruction to guarrantee a cache miss for
the reference. Does anyone know if the volatile nature of the reference
is available to the back end pattern matching mechanism for code generation?
If it is not, does anyone know how much trouble it would be to make it
available if one were willing to do the hacking?
Is the news software incompatible with your mailer too?
brooks@maddog.llnl.gov, brooks@maddog.uucp, uunet!maddog.llnl.gov!brooks