From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alessandro Rubini Date: Thu, 29 Jan 2009 11:37:11 +0100 Subject: [U-Boot] IP_t should be a "packed" struct In-Reply-To: <20090129102022.A71D3832E416@gemini.denx.de> References: <20090129102022.A71D3832E416@gemini.denx.de> <200901271932.11060.luigi.mantellini.ml@gmail.com> <49809C21.6070004@gmail.com> <4980A5AA.2090306@ge.com> <4980AAC3.7020601@gmail.com> <4980CC59.1070302@gmail.com> <20090128213828.13423832E416@gemini.denx.de> <20090128222747.CEBFD832E416@gemini.denx.de> Message-ID: <20090129103711.GA32504@mail.gnudd.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de > Now study the data structures used for netwrking - they are all > carefully crafted that the natural aligment "just fits", i. e. there > are no gaps between variables if they are aligned naturally. Actually, a packed structure not only doesn't have gaps, but can live at any address. So the compiler must access it byte-by-byte regardless. This means that a naturally-aligned structure performs much worse if declared as packed. And single-word loads and stores are not atomic any more. I tried with eldk-4.2 for arm and an older gcc for mips, I have no ppc or other archs handy right now: #include #include #ifdef PACKEDTEST # define P __attribute__ ((packed)) #else # define P #endif struct {uint32_t i; uint16_t s; uint8_t c, d;} P datum; uint32_t i; uint16_t s; uint8_t c; int main(int argc, char **argv) { printf("ih\n"); i = datum.i; printf("oh\n"); s = datum.s; printf("ah\n"); c = datum.c; return 0; } Compilation: ARM non-packed (only interesting lines): 8378: e5942000 ldr r2, [r4] 8384: e5832000 str r2, [r3] 838c: e1d420b4 ldrh r2, [r4, #4] 8398: e1c320b0 strh r2, [r3] 83a0: e5d42006 ldrb r2, [r4, #6] 83ac: e5c32000 strb r2, [r3] Compilation: ARM packed (only interesting lines): 8378: e5d42001 ldrb r2, [r4, #1] 837c: e5d43000 ldrb r3, [r4] 8380: e5d40002 ldrb r0, [r4, #2] 8384: e5d41003 ldrb r1, [r4, #3] 8388: e1833402 orr r3, r3, r2, lsl #8 838c: e1833800 orr r3, r3, r0, lsl #16 8394: e1833c01 orr r3, r3, r1, lsl #24 8398: e5823000 str r3, [r2] 83a4: e5d43005 ldrb r3, [r4, #5] 83a8: e5d42004 ldrb r2, [r4, #4] 83b0: e1822403 orr r2, r2, r3, lsl #8 83b8: e1c320b0 strh r2, [r3] 83c0: e5d42006 ldrb r2, [r4, #6] 83cc: e5c32000 strb r2, [r3] Compilation: MIPS non-packed (only interesting lines): 44: 8e030000 lw v1,0(s0) 5c: ac230000 sw v1,0(at) 74: 96030004 lhu v1,4(s0) 8c: a4230000 sh v1,0(at) a4: 92030006 lbu v1,6(s0) bc: a0230000 sb v1,0(at) Compilation: MIPS packed (only interesting lines): 44: 8a030003 lwl v1,3(s0) 48: 9a030000 lwr v1,0(s0) 60: ac230000 sw v1,0(at) 78: 92030005 lbu v1,5(s0) 7c: 92020004 lbu v0,4(s0) 80: 00031a00 sll v1,v1,0x8 84: 00621825 or v1,v1,v0 9c: a4230000 sh v1,0(at) b4: 92030006 lbu v1,6(s0) cc: a0230000 sb v1,0(at) /alessandro