I am trying to compile the libvpx library (webm decoder by google) with IAR embedded workbench for an ARM-A7 (bare metal application).
I managed to pull in all the necessary files, and it compiles, but there is a problem with the data alignment of some variables.
In the library, there is a macro DATA_ALIGNMENT() that expands to the GNUC __attribute__(aligned(n)) preprocessor directive. I think I managed to get this macro to work with the IAR version of data alignment (pragma data alignment), but I get the following warning
"Warning [Pe609]: this kind of pragma may not be used here"
and when I run the code, my variables are not aligned!
When searching for the warning on the internet, they say you cannot use pragma with definitions of the variables, but only when creating a variable of some kind! However, for data alignment you need to do it when defining the struct (and GCC does allow it, so why wouldnt IAR?)
Any help would be appreciated!
CODE
Macro Definitions:
#if (defined(__GNUC__) && __GNUC__) || defined(__SUNPRO_C)
#define DECLARE_ALIGNED(n, typ, val) typ val __attribute__((aligned(n)))
#elif defined(__ICCARM__)
#define CONCAT(a,b) a##b
#define DECLARE_ALIGNED(n, typ, val) CONCAT(DECLARE_ALIGNED_,n) (typ,val)
#define DECLARE_ALIGNED_1(typ, val) _Pragma("data_alignment=1") typ val
#define DECLARE_ALIGNED_8(typ, val) _Pragma("data_alignment=8") typ val
#define DECLARE_ALIGNED_16(typ, val) _Pragma("data_alignment=16") typ val
#define DECLARE_ALIGNED_32(typ, val) _Pragma("data_alignment=32") typ val
#define DECLARE_ALIGNED_256(typ, val) _Pragma("data_alignment=256") typ val
#else
#warning No alignment directives known for this compiler.
#define DECLARE_ALIGNED(n, typ, val) typ val
#endif
Example where used:
typedef struct VP9Decoder {
DECLARE_ALIGNED(16, MACROBLOCKD, mb);
DECLARE_ALIGNED(16, VP9_COMMON, common);
int ready_for_new_data;
int refresh_frame_flags;
...
} VP9Decoder;
I have tried this directly in my IAR compiler (7.40.6) and it works fine:
#define CONCAT(a,b) a##b
#define DECLARE_ALIGNED(n, typ, val) CONCAT(DECLARE_ALIGNED_,n) (typ,val)
#define DECLARE_ALIGNED_8(typ, val) _Pragma("data_alignment=8") typ val
typedef struct
{
int a;
char b;
char pad1;
char pad3;
char pad4;
int c;
char d;
} myType;
void main( void)
{
DELCARE_ALIGNED_4( myType, data);
// So data.a will be aligned to a 4 byte boundary
// data.b will be aligned to four bytes
// data.pad, pad1, pad2 are wasted space.
// data.c will be aligned to four bytes
// data.d will be aligned to four bytes
}
Unless you need to your struct to be in a specific order, for example mapping onto something, then ordering your struct carefully can reduce its size. For example, the padding I inserted in this case would quite likey be inserted by the compiler anyway. The order would be better as int a, int c, char b, char d.
as the original struct is probably 16 bytes long due to padding and alignment. Whereas it could to be made to be only 12.