Article View: gnu.gcc.bug
Article #2624the idea of a new feature for gcc
From: skubi%decprl.DEC
Date: Thu, 11 May 1989 18:29
Date: Thu, 11 May 1989 18:29
83 lines
3125 bytes
3125 bytes
Cc:
Gnu C should differentiate between ordinary RAM cells and hardware registers
mapped into (virtual or not) memory.
THE PROBLEM
I would like to suggest you a feature which seems to be necessary
if you want to write hardware drivers in optimized Gnu C. When a program
is optimized, the compiler performs a data flow analyzis which makes certain
variables not to be read/written the number of times requested by the
programmer. This is very suitable when the variable is a true RAM word,
but it changes the program semantics when the variable addresses a
hardware register mapped into virtual memory.
Example:
do {
res_brut = *adr;
} while (res_brut & 0x60000);
waits until a particular bit of a hardware device becomes equal to 0. And,
if I understand well your documentation, gcc considers it as equivalent to:
res_brut = *adr;
do {
} while (res_brut & 0x60000);
which is a non-sense.
So, following your specifications, I have no way to get sure that my
hadware driver will be compiled correctly by "gcc -O".
WHAT IS REQUIRED
In the program optimization, the compiler should consider accessing
hardware registers exactly as it considers calls to functions (other than
so-called constant functions): A hardware register access has side effects
and its value appears different each time it is read.
A SOLUTION
It should be possible to qualify any type as "hardware". For instance,
we could have "unsigned long int" as well as "hardware unsigned long int"
variables. "hardware" and ordinary types would follow exactly the same rules,
except for optimisation: the data flow analyzer would consider reading
and writing of hardware values as special, the compiler would not permute
or remove such operations.
Examples:
/* the example above, modified */
hardware long int adr*;
do {
res_brut = *adr;
} while (res_brut & 0x60000);
/* when the device's address is known in advance */
* ((hardware unsigned char *)0x123456) = 'a';
if * ((hardware unsigned char *)0x123456) printf ("error\n");
/* when the device's address is computed in a complicated way:
array contains the addresses of a few 2-word hardware registers. */
static hardware long int *(array[5]);
int i;
for (i=0; i<5; i++) {
array [i][0] = 0;
array [i][1] = 1;
}
/* typeof (array [i][0]) = hardware long int */
Friendly,
Marcin Skubiszewski.
skubi@decprl.dec.com
PS. Best wishes to GNU software, which is excellent.
Technical Details
Message-ID:
<8905111829.AA18182@decwrl.dec.com>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!DECWRL.DEC.COM!skubi%decprl.DECShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!DECWRL.DEC.COM!skubi%decprl.DEC From: skubi%decprl.DEC@DECWRL.DEC.COM Newsgroups: gnu.gcc.bug Subject: the idea of a new feature for gcc Message-ID: <8905111829.AA18182@decwrl.dec.com> Date: 11 May 89 18:29:36 GMT Sender: daemon@tut.cis.ohio-state.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 83