|m68k gcc/egcs question email@example.com (Zoltan Kocsi) (1999-09-20)|
|Re: m68k gcc/egcs question firstname.lastname@example.org (David Williams) (1999-09-24)|
|Re: m68k gcc/egcs question email@example.com (1999-09-24)|
|Re: m68k gcc/egcs question firstname.lastname@example.org (James Jones) (1999-09-27)|
|Re: m68k gcc/egcs question email@example.com (1999-09-28)|
|Re: m68k gcc/egcs question firstname.lastname@example.org (Zalman Stern) (1999-10-01)|
|Re: m68k gcc/egcs question email@example.com (Zoltan Kocsi) (1999-10-01)|
|[2 later articles]|
|From:||Zoltan Kocsi <firstname.lastname@example.org>|
|Date:||20 Sep 1999 12:13:01 -0400|
|Organization:||Bendor Research Pty. Ltd.|
|Keywords:||GCC, question, 68000|
Is anyone familiar with the m68k code generator of these compilers ?
I've got a few problems with them. One is the code efficiency:
The strcpy() code in this form:
char *a, *b;
while ( *a++ = *b++ );
compiles to this:
with gcc 126.96.36.199 using -O3; and to this:
with egcs-1.1.2 (-O3). Interestingly, the latter code is actually
slower than what is generated by the older gcc (which was already
slower than it should have been) ...
In addition, neither gcc nor egcs seem to treat the 'volatile'
qualifier in any sensible way.
Imagine the situation when you have a write-only hardware register
to which you want to dump a string. That is, you want to do something
volatile char *hw_reg;
*hw_reg = *the_string;
} while ( *the_string++ != '\0' );
Compiling this creates the same code on both compilers, namely:
which is just fine and is *exactly* what's written.
However, you might feel tempted to write it the short way:
while ( *hw_reg = *the_string++ );
expecting to get this more efficient assembly:
Now this is where your SW/HW interaction blows up because this is
what you get instead (on both compilers):
That is, they generate code that exactly maps to this C fragment:
*hw_reg = *the_string++;
} while ( *hw_reg != '\0' );
Whoops, reading a write-only register ...
Not to mention that it is not the same as the original while( ).
The original version said that get the data pointed by the (to be
postincremented) the_string pointer, stuff the data to the place
pointed by hw_reg and if the data was not zero, do it again.
What it does is this:
Get the data pointed by the (to be postincremented) the_string pointer,
stuff the data to the place pointed by hw_reg. Read a byte from the place
pointed by hw_reg and if non-zero, do the loop again.
Since hw_reg was declared volatile, the compiler should *not* assume that
writing to it then reading from it will give the same result.
I know that the standard states that any compiler can ignore the
volatile keyword. However, I had the apparently very dangerous assumption
that gcc et al treated volatile with some sensible way (i.e. the number
and order of read/write accesses is kept identical to what the C code
would do without optimisation).
Volatility of objects is obvious in regards to HW access. It should be
noted, however, that multithreaded code is a subject of the same
behaviour. Separate threads live in a common address space. Shared
variables (all globals, actually) are things which you can write to
and not necessarily read back the same value (because in the meantime
an other thread has overwritten it). For this very reason, when I tell
the compiler to put some data into a volatile location and, depending on
the *data*, do some action, it should change it to doing the action
depending on the volatile location's content instead.
Could anyone suggest me which forum / who should I contact to (hopefully)
get some resolution of that problem ?
| Zoltan Kocsi | I don't believe in miracles |
| Bendor Research Pty. Ltd. | but I rely on them. |
[Re volatile, the compiler is rereading the location exactly because it
can't assume that the same value is there. I've always claimed that
volatile isn't very useful, this is why. If you want reliable code to
deal with hardware registers, you need macros like write-to-location with
machine-specific implementations. -John]
Return to the
Search the comp.compilers archives again.