Dear Wolfgang Denk and Reinhard Meyer, The compiler (4.4.1) generates the expected 32bit store instruction when using:
struct p { int n; } __attribute__ ((packed, aligned(4))); In case of hardware registers, I have yet to see a case where this is not true. Regards, Francesco On Mon, Oct 4, 2010 at 2:43 PM, Reinhard Meyer <u-b...@emk-elektronik.de> wrote: > Dear Wolfgang Denk, > >> Dear Reinhard Meyer, >> >> In message <4ca9be94.6000...@emk-elektronik.de> you wrote: >>> Do you imply that the code is really different when the pointer gets >>> its value by assigning it NOT to a packed entity? Hard to believe. >> >> This is a special "feature" of GCC on ARM. >> >> -> cat foo.c >> #define writel(v,a) (*(volatile unsigned int *)(a) = (v)) >> >> struct p { >> int n; >> } __attribute__ ((packed)); >> >> struct q { >> int n; >> }; >> >> void foo() >> { >> struct p *pp = (struct p *)0x1000; >> >> pp->n = 5; >> } >> >> void bar() >> { >> struct q *qq = (struct q *)0x1000; >> >> qq->n = 5; >> } >> -> arm-linux-gcc -O -S foo.c >> -> cat foo.s >> .file "foo.c" >> .text >> .align 2 >> .global foo >> .type foo, %function >> foo: >> @ Function supports interworking. >> @ args = 0, pretend = 0, frame = 0 >> @ frame_needed = 0, uses_anonymous_args = 0 >> @ link register save eliminated. >> @ lr needed for prologue >> mov r3, #4096 >> mov r2, #0 >> orr r1, r2, #5 >> strb r1, [r3, #0] >> strb r2, [r3, #1] >> strb r2, [r3, #2] >> strb r2, [r3, #3] >> bx lr >> .size foo, .-foo >> .align 2 >> .global bar >> .type bar, %function > > In a non-packed struct an int will never be unaligned > (unless you use an unaligned pointer to the whole struct) > > In a packed struct an int might be unaligned, so it > _might_ make sense for the compiler to handle that > differently on ARM. Assume you overlay (bad idea anyway) > a packed structure over some communication data stream > thats is byte oriented. On most architectures that would > work (besides obvious endianess issues) but on ARM it would > (without raising an exception) malfunction. > [remember the "display_buffer issue"] > >> bar: >> @ Function supports interworking. >> @ args = 0, pretend = 0, frame = 0 >> @ frame_needed = 0, uses_anonymous_args = 0 >> @ link register save eliminated. >> @ lr needed for prologue >> mov r2, #5 >> mov r3, #4096 >> str r2, [r3, #0] >> bx lr >> .size bar, .-bar >> .ident "GCC: (GNU) 4.2.2" >> >> >> Note that this is with GCC 4.2.2. Even GCC 4.0.0 behaves the same, so >> this is *not* an issue with very recent tool chains. > > OK, for directly adressing elements inside a packed struct; > but the original post said: > > "struct xyz { > int x; > int y; > int z[CONST]; > } __attribute__ ((packed)); > > struct xyz *abc; > u32 * status_reg = (u32 *)&abc->z[0]; > > writel(status, status_reg);" > > So the "status_reg" pointer is in a completely unrelated (to the packed > struct) > "u32 *" and still the access is done like it was packed. If the > compiler silently drags that attribute along into the "u32 *" > THAT is really sick! > > Reinhard > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot