[gnu.gcc.bug] the idea of a new feature for gcc

skubi%decprl.DEC@DECWRL.DEC.COM (05/12/89)

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.

grunwald@flute.cs.uiuc.edu (05/12/89)

substitute ``volatile'' for ``hardware'' and check the Gnu C manual -
this feature already exists, and is ANSI C standard.
--
Dirk Grunwald
Univ. of Illinois
grunwald@flute.cs.uiuc.edu

mark@jhereg.Jhereg.MN.ORG (Mark H. Colburn) (05/12/89)

In article <8905111829.AA18182@decwrl.dec.com> skubi%decprl.DEC@DECWRL.DEC.COM writes:
>Gnu C should differentiate between ordinary RAM cells and hardware registers
>mapped into (virtual or not) memory.
> 
>Examples:
> 
>    /* the example above, modified */
>    hardware long int adr*;
>        do {
>        res_brut = *adr;
>    } while (res_brut & 0x60000);

The example that you gave is precisely the reason that the ANSI X3J11
commitee added the "volatile" keyword.  Volatile is to be used when the
compiler should not optimize away variable references since they may be
required to latch devices, or to read constantly changing memory.

I think that if you change your example above to read:

	volatile long int *adr;
	do {
	    res_brut = *adr;
	} while (res_brut & 0x60000);

You will get the results that you want.
-- 
Mark H. Colburn                          mark@jhereg.mn.org
Minnetech Consulting, Inc.

brooks@vette.llnl.gov (Eugene Brooks) (05/13/89)

In article <8905111829.AA18182@decwrl.dec.com> skubi%decprl.DEC@DECWRL.DEC.COM writes:
>Cc: 
> 
> 
>Gnu C should differentiate between ordinary RAM cells and hardware registers
>mapped into (virtual or not) memory.

Try using the ANSI C keyword volatile, this is what it is there for.


brooks@maddog.llnl.gov, brooks@maddog.uucp

stripes@wam.UMD.EDU (05/24/89)

>
>substitute ``volatile'' for ``hardware'' and check the Gnu C manual -
>this feature already exists, and is ANSI C standard.
>--
>Dirk Grunwald
>Univ. of Illinois
>grunwald@flute.cs.uiuc.edu

I have been looking over an ANSI C book from the Waite Group (I forget the
name, it's very small and is a kind-of refrence).  Anyway it says that
volatile registers are NOT restored after a longjmp(), nor are register
variables, but auto variables are.  GCC documation seems to say that only
volatile variables are restored.  Do I understand the GCC docs correctly?
Is the Waite Group book wrong, or is GCC, or what?
-- 
           stripes@wam.umd.edu
      Josh_Osborne@Real_World,The
      "The dyslexic porgramer"