Message ID | 20121025111705.GD11267@mudshark.cambridge.arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Will Deacon writes: > On Thu, Oct 25, 2012 at 07:55:22AM +0100, Artem Bityutskiy wrote: > > On Wed, 2012-10-24 at 11:52 +0100, Will Deacon wrote: > > > (a) Understand what has changed in GCC to cause this error to start > > > cropping up. > > > > This is about already quite old gcc 4.6.3, which I use for about 4 last > > kernel releases already. So it is only the kernel that changed. > > Looks like it's broken with gcc 4.7 too, so it might be that it's never > worked. The problem seems to be that offsettable addresses are assumed by > GCC to have a 12-bit immediate range, which isn't true for half- and double- > work accessors, so GAS barfs when presented with the final (invalid) code. ... > Unfortunately, GCC doesn't give us another constraint > that we can use for this, so I think we just have to grin and bear it. Please file a GCC bugzilla entry with an enhancement request to support ARM constraint letters for other immediate sizes than 12 (and list which sizes are missing).
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 35c1ed8..42f042e 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -64,7 +64,7 @@ extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); static inline void __raw_writew(u16 val, volatile void __iomem *addr) { asm volatile("strh %1, %0" - : "+Qo" (*(volatile u16 __force *)addr) + : "+Q" (*(volatile u16 __force *)addr) : "r" (val)); } @@ -72,7 +72,7 @@ static inline u16 __raw_readw(const volatile void __iomem *addr) { u16 val; asm volatile("ldrh %1, %0" - : "+Qo" (*(volatile u16 __force *)addr), + : "+Q" (*(volatile u16 __force *)addr), "=r" (val)); return val; }