There are lots of complex rules on getting structures sized the way one wants on an i960 for consistency with other machines. By default, i960 GCC aligns structures and objects such that they are on the next higher power of 2 boundary (up to a maximum of 16 bytes). We want to change this to pack data tightly. When doing this, we need to avoid one capability of GCC; making enum types only as big as needed to hold the range of values.
GCC allows "short" enum types. The option -fshort-enums
turns on this option (it is not on by default unless the compiler is
built to emulate the Intel i960 tools which isn't the case with VxWorks).
The option -fno-short-enums
turns it off. As long as we
don't turn on -fshort-enums
then enumerated types should be
set up as 32 bit words the way we want (regardless of other packing).
There are two ways to affect data packing in GCC; pragmas and attributes. Attributes are GCC specific. The GCC doc says to always use attributes because:
Some people object to theThere are type and variable attributes explained in the GCC documentation but pragma's aren't really explained.__attribute__
feature, suggesting that ANSI C's#pragma
should be used instead. There are two reasons for not doing this.These two reasons apply to almost any application that might be proposed for
- It is impossible to generate
#pragma
commands from a macro.- There is no telling what the same
#pragma
might mean in another compiler.#pragma
. It is basically a mistake to use#pragma
for anything.
Attributes are applied after the '}' in typedefs and after the variable name in variable defs.
I did some testing to try to check packing. I took a structure and tried
to pack it. I added an extra single byte value to the structure to make
it an "odd" size. I found that I got optimal packing by applying
"pragma align 1
" and "attribute packed
" to the
structure. Note, I couldn't use the "aligned
" attribute to
achieve the same effect as the "aligned
" pragma because
"pragma aligned"
is recognized in the i960 specific GCC code
as a way to lower the default alignment applied whereas the
"aligned
" attribute can only be used to increase the minimum
alignment. Thus we need to use the alignment pragma and packing
attribute.
The packing attribute is "__attribute__((packed))
". We can
implement this packing attribute string as a macro:
#define PACK_STRUCT __attribute__((packed))
This is good since this string screws up the C "indent" program we use if entered directly.
So it seems we should use "#pragma align (1)
" and
"#pragma align (0)
" to bracket portable structure
definitions and the macro PACK_STRUCT
on the structure
definitions. The PACK_STRUCT
macro has to be applied to all
nested structures too.
To avoid portability problems we should conditionally define
PACK_STRUCT
for the i960 and bracket all the alignment
pragmas as follows:
/* definitions to change alignment to be tightly packed and then restore * it to default alignment (16 bytes) */ #ifdef I960 #pragma align 1 #endif #ifdef I960 #pragma align 0 #endif
EXAMPLE:
Given this, I would code your example as:
/* set tight packing */ #ifdef I960 #define PACK_STRUCT __attribute__((packed)) #pragma align 1 #else #define PACK_STRUCT #endif struct A { short x short y struct B { char a char b char c char d[..] } PACK_STRUCT; } PACK_STRUCT; /* restore default packing */ #ifdef I960 #pragma align 0 #endif
CAVEAT:
So, I hope this explanation helps. I found that I got the results I wanted with it but I always defined the structures with typedefs as in:
typedef struct { ... } PACK_STRUCT NAME_T;
You didn't include any names in your example but I think if you had, the
PACK_STRUCT
would go after the object name.
As a last note, there was one little "nasty" thing I came across with this. When I was doing this work (a few years ago so the details are a bit fuzzy), I found that the assembler code generated for accessing packed structures ended up using all byte accesses even where the data was properly aligned for larger access operations. I don't remember if this was affected by optimization or not. I would just suggest not to bother packing things unless you need to.
|