Path: 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 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.