------- Additional Comments From neroden at gcc dot gnu dot org  2005-07-15 
05:50 -------
OK, so in X.org, the key area where this is hit is the definition of     
MMIO_IN8 in compiler.h.  For alpha, sparc, and powerpc, inline volatile     
ASM is used instead (much better in some ways).     
     
The vanishing line is:       
(void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);       
This expands in preprocessing to:       
(void) MMIO_IN8(hwp->MMIOBase, (hwp->MMIOOffset + (hwp->IOBase +      
VGA_IN_STAT_1_OFFSET)))       
which further expands in preprocessing in compiler.h (except for     
sparc, alpha and powerpc) to:     
(void) *(volatile CARD8 *)( (CARD8*)(hwp->MMIOBase) + hwp->MMIOOffset +     
hwp->IOBase + VGA_IN_STAT_1_OFFSET)     
     
The key expansion is this one:     
#  define MMIO_IN8(base, offset) \     
        *(volatile CARD8 *)(((CARD8*)(base)) + (offset))     
     
This obviously doesn't work and perhaps it shouldn't work.  But what is a     
good alternative implementation?  Essentially, we're trying to force a read  
of an arbitrary memory address.  If the "underlying object" has  
to be volatile, how do we make it volatile?  Can we simply create a new  
"underlying object" by throwing in a temporary pointer variable?  Is something  
like the following sufficient to force an access?  
  
static inline unsigned char myMmioIn8(volatile void* base,  
                                      const unsigned long offset)  
{  
  volatile CARD8 * tmp = (CARD8*)base + offset;  
  return *tmp;  
}  
#  define MMIO_IN8(base, offset) myMmioIn8(base, offset)    
  
If that's not sufficient, I don't see any way to accomplish the required  
behavior under gcc 4.0 (without massive rewriting of the X.org code), so I 
hope it is.  
  

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22278

Reply via email to