------- 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