S
Sven Köhler
Hi,
I'm currently trying to find out which possibilities exist to access a
4byte aligned int64_t. I know, that I could declare a union of int64_t
and two int32_t and copy each int32_t independently to the struct. This
works. But the assembly code that gcc generates is - well - not optimal.
I tried what happened if I simply cast 4byte aligned pointer to an
int64_t pointer. I know that that's basically forbidden and isn't
portable. But the assembly code was much nice. Also, my primary target
architecture (arm 32bit) has a "load double word" instruction, that only
works with 8byte aligned pointers. So obviously, I was just lucky gcc
didn't end up using the "load double word" instruction.
Currently, I'm experimenting with packed structs. Consider the following :
typedef struct __attribute__((packed)) {
int64_t x;
} s1;
The code uses a gcc extension (the packed attribute). Given a variable
s1 *p, gcc loads the value of p->x byte-wise (i.e. using arm's ldrb
instruction). This seems strange to me because according to the
documentation, the packed attribute ensures that no alignment padding is
used. But first of all, sizeof s1 is equal to 8. Secondly, the member x
is at offset 0 of the struct. So it seems to me, that one could not
obtain any pointers of type s1* without cheating heavily (e.g. by
casting unaligned pointers to s1*). clang also loads p->x byte by byte.
Am I wrong and the compiler must expect that a pointer to s1 may have an
alignment less than 8? If yes, then a packed struct is exactly what I'm
looking for. I already tested the following:
typedef struct __attribute__((packed)) {
__attribute__((aligned(4))) int64_t x;
} s4;
Both gcc and clang load the value of member x word-wise, half-word-wise,
or byte-wise depending on whether the aligned attribute indicates 4, 2,
or 1-byte alignment.
Using the the packed attribute without a struct or specifying the
alignment attribute didn't work. The packed attribute does only seem to
be for structs. The alignment attribute can only increase but not
decrease the alignment.
Any thoughts?
I'm not afraid of using gcc extension, but the code should be portable.
Regards,
Sven
I'm currently trying to find out which possibilities exist to access a
4byte aligned int64_t. I know, that I could declare a union of int64_t
and two int32_t and copy each int32_t independently to the struct. This
works. But the assembly code that gcc generates is - well - not optimal.
I tried what happened if I simply cast 4byte aligned pointer to an
int64_t pointer. I know that that's basically forbidden and isn't
portable. But the assembly code was much nice. Also, my primary target
architecture (arm 32bit) has a "load double word" instruction, that only
works with 8byte aligned pointers. So obviously, I was just lucky gcc
didn't end up using the "load double word" instruction.
Currently, I'm experimenting with packed structs. Consider the following :
typedef struct __attribute__((packed)) {
int64_t x;
} s1;
The code uses a gcc extension (the packed attribute). Given a variable
s1 *p, gcc loads the value of p->x byte-wise (i.e. using arm's ldrb
instruction). This seems strange to me because according to the
documentation, the packed attribute ensures that no alignment padding is
used. But first of all, sizeof s1 is equal to 8. Secondly, the member x
is at offset 0 of the struct. So it seems to me, that one could not
obtain any pointers of type s1* without cheating heavily (e.g. by
casting unaligned pointers to s1*). clang also loads p->x byte by byte.
Am I wrong and the compiler must expect that a pointer to s1 may have an
alignment less than 8? If yes, then a packed struct is exactly what I'm
looking for. I already tested the following:
typedef struct __attribute__((packed)) {
__attribute__((aligned(4))) int64_t x;
} s4;
Both gcc and clang load the value of member x word-wise, half-word-wise,
or byte-wise depending on whether the aligned attribute indicates 4, 2,
or 1-byte alignment.
Using the the packed attribute without a struct or specifying the
alignment attribute didn't work. The packed attribute does only seem to
be for structs. The alignment attribute can only increase but not
decrease the alignment.
Any thoughts?
I'm not afraid of using gcc extension, but the code should be portable.
Regards,
Sven