linux-mips
[Top] [All Lists]

Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementatio

To: Andrew Morton <akpm@linux-foundation.org>
Subject: Re: [PATCH] Optimize generic get_unaligned / put_unaligned implementations.
From: Marcel Holtmann <marcel@holtmann.org>
Date: Thu, 15 Feb 2007 09:35:16 +0100
Cc: Ralf Baechle <ralf@linux-mips.org>, Atsushi Nemoto <anemo@mba.ocn.ne.jp>, linux-mips@linux-mips.org, linux-kernel@vger.kernel.org
In-reply-to: <20070214203903.8d013170.akpm@linux-foundation.org>
Original-recipient: rfc822;linux-mips@linux-mips.org
References: <20050830104056.GA4710@linux-mips.org> <20060306.203218.69025300.nemoto@toshiba-tops.co.jp> <20060306170552.0aab29c5.akpm@osdl.org> <20070214214226.GA17899@linux-mips.org> <20070214203903.8d013170.akpm@linux-foundation.org>
Sender: linux-mips-bounce@linux-mips.org
Hi Andrew,

> > +#define get_unaligned(ptr)                                         \
> > +({                                                                 \
> > +   const struct {                                                  \
> > +           union {                                                 \
> > +                   const int __un_foo[0];                          \
> > +                   const __typeof__(*(ptr)) __un;                  \
> > +           } __un __attribute__ ((packed));                        \
> > +   } * const __gu_p = (void *) (ptr);                              \
> > +                                                                   \
> > +   __gu_p->__un.__un;                                              \
> >  })
> 
> Can someone please tell us how this magic works?  (And it does appear to
> work).
> 
> It seems to assuming that the compiler will assume that members of packed
> structures can have arbitrary alignment, even if that alignment is obvious.
> 
> Which makes sense, but I'd like to see chapter-and-verse from the spec or
> from the gcc docs so we can rely upon it working on all architectures and
> compilers from now until ever more.

I am far away from having any knowledge about the GCC internals and the
reason why this code works, but I've been told the generic way of
handling unaligned access is this:

#define get_unaligned(ptr)                      \
({                                              \
        struct __attribute__((packed)) {        \
                typeof(*(ptr)) __v;             \
        } *__p = (void *) (ptr);                \
        __p->__v;                               \
})

#define put_unaligned(val, ptr)                 \
do {                                            \
        struct __attribute__((packed)) {        \
                typeof(*(ptr)) __v;             \
        } *__p = (void *) (ptr);                \
        __p->__v = (val);                       \
} while(0)

Actually I am using this code in the Bluetooth userspace library for
over two years now without any complaints.

Regards

Marcel



<Prev in Thread] Current Thread [Next in Thread>