I'm writing program in C language for mipsisa32 architecture that works with ECOS operating system. This is the first time I'm working with ecos and mips, and I get strange problem. I use dynamically allocated chunk of memory and I write some data to it. But when I try to write double value to address that is not aligned to 8 bytes, I get exception number 5, which is declared in hal_intr.h as CYGNUM_HAL_VECTOR_STORE_ADDRESS, and later redefined as CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_WRITE.
If I take pointers to destination and source and cast them to long long*, and them assign value from one to another then I don't get exception.
Same thing happens when reading double from unaligned address, but only with double, and not with long long. It does make sense, because assembly code really does use different instructions. I don't know mips assembly but from what I've seen I concluded that when storing/reading long long it does so in two chunks of 4bytes, but for double it does it in one step.
So what do you suggest? Is this normal behavior?
My last resort is to make sure myself, that addresses are aligned, which would add extra overhead since I write to many dynamically allocated buffers.
IIRC MIPS does not support unaligned memory accesses. You might be violating the requirement for
malloc
to return blocks properly aligned for any datatype.double
as fetched as a single 64 bit word. So it requires an alignment of 8 bytes (here: 8 bits). For long long: on a 32 bit (word) architecture, that is emulated using two registers with 32 bit memory accesses (a load double-word instruction asLDRD
on ARM is basically two word load instructions). So 4 bytes is a sufficientl (yet possibly not optimal) alignment.I assume you are currently aligning to word-boundaries. You should align to
max_align_t
(C11) or similar (pre-C11) to be on the safe side.