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
rtsbrooks@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