How can C code take advantage of the Cortex M4's unaligned 4-byte store instruction?
*(int*)p = x
mostly works, but occasionally I end up with something like this:
void Store(uint8_t* p, uint32_t a, uint32_t b)
{
*(uint32_t*)(p + 0) = a;
*(uint32_t*)(p + 4) = b;
}
which gcc
then compiles to:
00000000 <Store>:
0: e9c0 1200 strd r1, r2, [r0]
4: 4770 bx lr
6: bf00 nop
which of course gives a HardFault
because 8-byte stores must be aligned. Is there a way to write the stores so that gcc knows they can be unaligned? Is there maybe an unaligned int type, perhaps?
Sinc you are using GCC, you can use a packed structure:
struct p { uint32_t u; } __attribute__((__packed__));
void Store(void *vp, uint32_t a, uint32_t b)
{
struct p *pp = vp;
pp[0].u = a;
pp[1].u = b;
}
This generates:
Store:
str r1, [r0] @ unaligned
str r2, [r0, #4] @ unaligned
bx lr
Note that you should consider the aliasing rules when doing this. If the destination is defined with a different type, storing the data with this structure type could require some workaround for that.