[Bug target/67246] MIPS: lw (load word) is generated for byte bitfield, leading to unaligned access
kugel at rockbox dot org
gcc-bugzilla@gcc.gnu.org
Mon Aug 17 09:46:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67246
--- Comment #2 from Thomas Martitz <kugel at rockbox dot org> ---
Thanks for your immediate reply.
In trying to provide a better test case I think I've found what the culprit is.
The full iphdr defintion is:
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8 version:4,
ihl:4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 tos;
__be16 tot_len;
__be16 id;
__be16 frag_off;
__u8 ttl;
__u8 protocol;
__sum16 check;
__be32 saddr;
__be32 daddr;
/*The options start here. */
};
Note that it ends with 32bit saddr and daddr fields.
If I change these to __be16, then the following code is generated:
248: 96220000 lhu v0,0(s1)
24c: 8fa40044 lw a0,68(sp)
250: 7c421a00 ext v0,v0,0x8,0x4
254: 00021080 sll v0,v0,0x2
258: 00821021 addu v0,a0,v0
So I guess that means the 32bit fields change the alignment of the whole struct
to 4 byte. And then the compiler assumes iph must be 4-byte aligned (in a
conformant program).
The linux code carefully avoids accessing saddr and daddr fields near this code
(not shown above) so I guess it's aware of the potentially unaligned access.
So I'm not sure anymore who's on fault now
More information about the Gcc-bugs
mailing list