Just to clarify things:
If you have a struct like this:

struct {
        unsigned int a;
        unsigned char p1;
        unsigned int b;
        unsigned char p2;
        unsigned char p3;
        unsigned char p4;
        unsigned int c;
} __packed;

without __attribute__((aligned(4))), gcc will generate
alignment-safe code when accessing fields a, b and c.
with __attribute__((aligned(4))), gcc will do direct
access for fields a and c, and alignment-safe access for
field b.

In the specific case of athn(4), all fields in descriptors
are 32-bit, so __packed is probably not necessary, but I
like my hardware structs to be __packed.

Damien

| Add __attribute__((aligned(4))) to __packed Tx/Rx descriptors.
| This makes gcc generate much more efficient code on architectures
| with strong alignment constraints (like sparc64).
| We use __packed to tell the compiler to not insert padding between
| fields but the start of the descriptors is always 32-bit aligned.
| When __packed is used, gcc assumes worst case scenario and generates
| complicated code to prevent unaligned accesses.
| 
| Inspired by a similar change to ath9k.
| Tested on sparc64.
| 
| For the record, example to set a field to 1 on a sparc64:
| without __attribute__((aligned(4))):
| ldub    [%g2], %g1
| and     %g1, 0, %g1
| stb     %g1, [%g2]
| ldub    [%g2+1], %g1
| and     %g1, 0, %g1
| stb     %g1, [%g2+1]
| ldub    [%g2+2], %g1
| and     %g1, 0, %g1
| stb     %g1, [%g2+2]
| ldub    [%g2+3], %g1
| and     %g1, 0, %g1
| or      %g1, 1, %g1
| stb     %g1, [%g2+3]
| 
| with __attribute__((aligned(4))):
| mov     1, %g1
| st      %g1, [%g2]

Reply via email to