Grant Edwards @ Thu, 14 Feb 2008 02:01:52 +0000 (UTC)

>>> It wasn't clear to me that the web page mentioned earlier was
>>> saying that.  That web page seemed to be talking about
>>> peripheral registers.
>>
>> Any unaligned struct members *and* structures themselves on
>> RISC generally, i guess. Better to ask developers. There is an
>> alternative -- byte by byte access.
>
> I don't understand.  An "alternative" to what?

"byte reads for the larger integer types" (Chris) vs what you have now.

> It's what gcc does on other targets when accessing misaligned packed
> struct members.

GCC or http://lxr.linux.no/linux/include/asm-generic/unaligned.h


>> But how efficient it can be? Better to have good _design_
>> right from the start.
>
> If you don't get to define the layout of the data in memory, I
> don't see how you can "design" your way around doing byte by
> byte access of misaligned values.

For this case

| typedef struct tTestPointer
|   {
|     uint8_t m;
|     uint16_t k;
|     uint32_t l;
|   } __attribute__ ((packed)) tTestPointer;

padding can be inserted after 'm' (gcc) or *before* (by design). Latter,
as it seems, is going to work for wire protocols without overhead. No?

Let's check it.

====
ole...@flower:/tmp$ cat <./unaligned.c
#if defined(NOPAD)
#  define LAYOUT        __attribute__((packed))
#else
#  define LAYOUT
#endif

#if defined(DESIGN)
#  define __u8_pad__    unsigned char u8_pad; /* hack */
#else
#  define __u8_pad__
#endif

static struct LAYOUT {
    __u8_pad__
    unsigned char u8;
    unsigned short u16;
    unsigned long u32;
} data;

int main(void)
{
        data.u8  = 0x01;
        data.u16 = 0x01EC;
        data.u32 = 0xFEDCBA98;

        return data.u8 + data.u16 + data.u32;
}

ole...@flower:/tmp$
ole...@flower:/tmp$ msp430-gcc -DDESIGN -Wpadded -S -fverbose-asm -O2 -o 
O2_unaligned_hack.S unaligned.c
ole...@flower:/tmp$ msp430-gcc -DNOPAD  -Wpadded -S -fverbose-asm -O2 -o 
O2_unaligned_nopad.S unaligned.c
ole...@flower:/tmp$ msp430-gcc          -Wpadded -S -fverbose-asm -O2 -o 
O2_unaligned.S unaligned.c
unaligned.c:16: warning: padding struct to align `u16'
ole...@flower:/tmp$

== GCC padding vs GCC packing ==

Suppose 'data' is naturally aligned (16 bits).

ole...@flower:/tmp$ diff -u1 O2_unaligned.S O2_unaligned_nopad.S                
                          --- O2_unaligned.S      2008-02-14 05:36:09.808877250 
+0100
+++ O2_unaligned_nopad.S        2008-02-14 05:35:46.159399250 +0100
@@ -9,3 +9,3 @@
  ;  -D__SIZE_TYPE__=unsigned int -D__PTRDIFF_TYPE__=int -D__INT_MAX__=32767
- ;  -O2 -Wpadded -fverbose-asm
+ ;  -DNOPAD -O2 -Wpadded -fverbose-asm
  ;  options enabled:  -fdefer-pop -fomit-frame-pointer
@@ -36,4 +36,4 @@
    mov.b       #llo(1), &data   ;   data.u8
-   mov #llo(492), &data+2       ;   data.u16
-   mov #data+4, r15
+   mov #llo(492), &data+1       ;   data.u16
+   mov #data+3, r15
    mov #llo(-19088744), @r15    ;   data.u32

!! unaligned access: data+1, data+3

@@ -51,3 +51,3 @@
    .local data
-   .comm data,8,2
+   .comm data,7,2

== GCC padding vs Design hacking ==

ole...@flower:/tmp$ diff -u1 O2_unaligned.S O2_unaligned_hack.S
--- O2_unaligned.S      2008-02-14 05:36:09.808877250 +0100
+++ O2_unaligned_hack.S 2008-02-14 05:35:41.479106750 +0100
@@ -9,3 +9,3 @@
  ;  -D__SIZE_TYPE__=unsigned int -D__PTRDIFF_TYPE__=int -D__INT_MAX__=32767
- ;  -O2 -Wpadded -fverbose-asm
+ ;  -DDESIGN -O2 -Wpadded -fverbose-asm
  ;  options enabled:  -fdefer-pop -fomit-frame-pointer
@@ -35,3 +35,3 @@
 /* prologue end (size=2) */
-   mov.b       #llo(1), &data   ;   data.u8
+   mov.b       #llo(1), &data+1         ;   data.u8
    mov #llo(492), &data+2       ;   data.u16
                   ^^^^^^^
!! access is aligned

ole...@flower:/tmp$ diff -u1 O2_unaligned_hack.S O2_unaligned_nopad.S
--- O2_unaligned_hack.S 2008-02-14 05:35:41.479106750 +0100
+++ O2_unaligned_nopad.S        2008-02-14 05:35:46.159399250 +0100
@@ -9,3 +9,3 @@
  ;  -D__SIZE_TYPE__=unsigned int -D__PTRDIFF_TYPE__=int -D__INT_MAX__=32767
- ;  -DDESIGN -O2 -Wpadded -fverbose-asm
+ ;  -DNOPAD -O2 -Wpadded -fverbose-asm
  ;  options enabled:  -fdefer-pop -fomit-frame-pointer
@@ -35,5 +35,5 @@
 /* prologue end (size=2) */
-   mov.b       #llo(1), &data+1         ;   data.u8
-   mov #llo(492), &data+2       ;   data.u16
-   mov #data+4, r15
+   mov.b       #llo(1), &data   ;   data.u8
+   mov #llo(492), &data+1       ;   data.u16
+   mov #data+3, r15
    mov #llo(-19088744), @r15    ;   data.u32

!! this is OK on x86, but on msp430 is not, as we saw in the first posting

@@ -51,3 +51,3 @@
    .local data
-   .comm data,8,2
+   .comm data,7,2

ole...@flower:/tmp$
--
-o--=O`C
 #oo'L O
<___=E M


Reply via email to