This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

struct packing reliability?


Hello all;

I'm trying to make a consistent C interface to various sets of hardware 
registers on the Gameboy Advance by using packed structs: for instance, there 
is an area of memory which stores an array of 128 64-bit 'objects' which look 
like this:

  #define PACKED __attribute__((packed))
  ...
  struct _gba_ObjEntry  
  {
      /****** attribute 0 */

      /* Y position of Obj */
      unsigned int y : 8;
    
      /* Whether to apply rotation and scaling */
      unsigned int rotateAndScale : 1;
    
      /* */
      unsigned int sizeDouble : 1;
     
      /* */
      unsigned int alphaMode : 2;
    
      /* */
      unsigned int mosaic : 1;
    
      /* Indicates that a Obj is 256 colour, not 16 */
      unsigned int is256colour : 1;
    
      /* Lower two bits of Obj size constant */
      enum { Square, Tall, Wide } PACKED shape : 2;
    
      /****** attribute 1 */
    
      /* X position of Obj */
      unsigned int x : 9;
     
      union
      {
  	  unsigned int rotationIndex : 5;
	  struct
  	  {
	      unsigned int unused : 3;
	    
	      unsigned int x : 1;
	      unsigned int y : 1;
	  } PACKED
	  flipFlags;
      } PACKED
      transform;
    
      /* Upper two bits of Obj size constant */
      enum { Size8, Size16, Size32, Size64 } PACKED size : 2;
    
      /****** attribute 2 */
    
      /* The index of the tile in */
      unsigned int firstCharacterIndex : 10;

      /* Higher priority Objs are plotted over lower priority Objs */
      unsigned int priority : 2;
    
      /* Which palette to use, only relevant for 16 colour Objs */
      unsigned int paletteNumber : 4;
    
      /****** attribute 3 */
    
      unsigned int rotationInformation : 16;
    
  } PACKED;

Now as far as I can tell these add up to 64 bits, so I was hoping that I 
could define an array at the correct memory address and have this Just Work.  
Unfortunately, sizeof(_gba_ObjEntry) == 10, not 8 as I'd expected.  My GCC 
version gives these diagnostics:

  mattbee> arm-agb-elf-gcc -v
  Reading specs from 
/usr/local/devkitadv/bin/../lib/gcc-lib/arm-agb-elf/3.0.1/specs
  Configured with: ../gcc-3.0.1/configure --prefix=/devkitadv 
--target=arm-agb-elf --with-cpu=arm7tdmi --without-local-prefix --with-newlib 
--with-headers=../newlib-1.9.0/newlib/libc/include/ --with-gc=simple 
--enable-multilib --enable-interwork --enable-languages=c++ 
--enable-targets=arm-elf,arm-coff,arm-aout --disable-win32-registry 
--disable-threads -v
  Thread model: single
  gcc version 3.0.1 (DevKit-Advance)

I have a feeling my structs and unions inside structs complicate matters, but 
I can't be sure.  My question is: is there any way of getting gcc to pack the 
above struct to exactly 64 bits, or should I give up and use hardware 
definitions as a set of ugly #defines ?  I'd really rather do it this way if 
I can, since I'm able to use some handy C semantics rather than needing to do 
lots of tedious bit clearing and shifting to get the right results.  Even if 
gcc *can* be forced to do this, is this a bad route to go down on account of 
this behaviour being unenforceable?  I'd be reasonably happy if only gcc 
could do it but from the documentation I'm beginning to have my doubts.

cheers,

-- 
Matthew       > http://www.soup-kitchen.net/
              > ICQ 19482073


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]