public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Data alignment question
@ 2002-02-14  8:21 Joe MacDonald
  0 siblings, 0 replies; only message in thread
From: Joe MacDonald @ 2002-02-14  8:21 UTC (permalink / raw)
  To: gcc-help; +Cc: bruce


Hi all,

I'm having a problem with the way our compiler is aligning some members
of a structure. I've spent a significant amount of time trying to
determine why things are happening, but I've now hit a roadblock.

The code is running on a ppc750 chip and is tightly coupled to the
structure and memory map of an ASIC, so I don't have much flexibility in
my strucutre layout, hence my problem.

The stats on the compiler we are using:

>Configured with: /proj/tools/targetToolchain/src/gcc-3.0/configure --target=powerpc-ecos-eabi --prefix=/proj/SDE/v1.1 --with-gnu-as --with-gnu-ld --with-newlib
>Thread model: single
>gcc version 3.0

Although most of the code is C, we are using the g++ for some of it's
"extra" features. Here are the minimal compile flags that are being used
on most of our phases. I've tried adding and removing these flags and a
few others without any change for the better (it did get worse without
the -mno-bit-align!)

powerpc-ecos-eabi-c++ -g -O0 -fno-builtin -mno-bit-align -mstrict-align -c align.c

The problem that I'm seeing has to do with some structures being padded
out to either byte or word boundaries, and causing my values to
mis-aligned when communicating the the h/w. I've read the relevant gcc
docs and have tried liberal use of both the: __attribute__((packed)) and
the __attribute__((align(x))) extension without any luck.

Here is a snippet of code that illustrates the problem:

------------------------------------------------------------------------
typedef  unsigned short Uint8;
typedef  unsigned long  Uint32;

typedef struct dmaBuffer
{
   Uint8  flag_m        : 1; 
   Uint8  state_m       : 4;
   Uint8  addressHigh_m : 8; 
   Uint32 address_m     : 32; 
   Uint32 lpb_m         : 16;
   Uint32 lvb_m         : 16;
   
} dmaBuffer_t;

typedef struct dmaDescriptor
{
   Uint8 queue_m               :8;
   Uint8 bufferPtr_m           :1;
   Uint8 buffFlag_m            :1;   
   Uint8 unusedA_m             :1;
   
   dmaBuffer_t bufferA_m; 
   
   Uint32  unusedB_m :19;
   
   dmaBuffer_t bufferB_m;
   
} dmaDescriptor_t;

typedef struct bufInfo
{
   Uint8 flag_m :1;
   Uint8 code_m :7;

   union
   {
      dmaDescriptor_t  dma_m;
   }  payload_m;
   
} bufInfo_t;

bufInfo_t buffer;
------------------------------------------------------------------------

Browsing the object file reveals the following alignment:

   typedef       struct {
         flag_m ()
         state_m ()     [1..4]
         addressHigh_m ()       [5..12]
         address_m ()   [13..44]
         lpb_m ()       [45..60]
         lvb_m ()       [61..76]
      } dmaBuffer (dmaBuffer)

   typedef       struct {
         queue_m ()     [0..7]
         bufferPtr_m () [8..8]
         buffFlag_m ()  [9..9]
         unusedA_m ()   [10..10]
         bufferA_m ()   [16..95]
         unusedB_m ()   [96..114]
         bufferB_m ()   [120..199]
      } dmaDescriptor (dmaDescriptor)

   typedef       struct {
         flag_m ()
         code_m ()      [1..7]
         union {
            dma_m ()    [0..199]
         }       payload_m () [8..207]
      } bufInfo (bufInfo)

The problem is with the bufferA_m member of the dmaDescriptor structure
being padded out to [16..95] and again with bufferB_m. I understand why
the compiler want to do this, but I can't seem to instruct it to do
otherwise. The interesting part is that if I remove the bufferA_m and
bufferB_m members of the structure and replace them with all the fields
found in that structure I get the following:

   typedef       struct {
         flag_m ()
         state_m ()     [1..4]
         addressHigh_m ()       [5..12]
         address_m ()   [13..44]
         lpb_m ()       [45..60]
         lvb_m ()       [61..76]
      } dmaBuffer (dmaBuffer)

   typedef       struct {
         queue_m ()     [0..7]
         bufferPtr_m () [8..8]
         buffFlag_m ()  [9..9]
         unusedA_m ()   [10..10]
         flagA_m ()     [11..11]
         stateA_m ()    [12..15]
         addressHighA_m ()      [16..23]
         addressA_m ()  [24..55]
         lpbA_m ()      [56..71]
         lvbA_m ()      [72..87]
         unusedB_m ()   [88..106]
         flagB_m ()     [107..107]
         stateB_m ()    [108..111]
         addressHighB_m ()      [112..119]
         addressB_m ()  [120..151]
         lpbB_m ()      [152..167]
         lvbB_m ()      [168..183]
      } dmaDescriptor (dmaDescriptor)

   typedef       struct {
         flag_m ()
         code_m ()      [1..7]
         union {
            dma_m ()    [0..183]
         }       payload_m () [8..191]
      } bufInfo (bufInfo)

Not a gap or padding to be found. Does anyone have any suggestions to
where applying extensions, compiler flags or other changes might affect
the padding in the first layout of the code ? I realize that the structs
aren't optimal, but they are what I'm stuck with right now.

Thanks,
-Joe.

-- 
Joe MacDonald
:wq

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2002-02-14 16:07 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-02-14  8:21 Data alignment question Joe MacDonald

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).