I recently tested the ARM port on an older ARM system (Marvell
Kirkwood ARMv5TE) and found an issue which did not happen with the
raspberry. This source file:

----------------------------------------------
import std.stdio;
void main()
{
    ubyte[4] data = cast(ubyte[4])[1,1,1,1];
    *cast(ushort *)&data[1] = 0;
    writeln(data);
}
----------------------------------------------
(reduced from std.zip)

Produces this ASM:
----------------------------------------------
sub     r3, fp, #8         ;r3 = &data
add     r3, r3, #1         ;r3 = &data[1]
mov     r2, #0             ;r2 = 0
strh    r2, [r3]           ;&data[1] = (ushort)0
----------------------------------------------

Output on raspberry:
----------------------------------------------
[1, 0, 0, 1]
----------------------------------------------

Output on kirkwood (same binary):
----------------------------------------------
[0, 0, 1, 1]
----------------------------------------------

Debugging shows that the 'strh' instruction corrupts the data. After
some research I found this:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0068b/BABDJCHA.html
"a non halfword-aligned 16-bit save corrupts two bytes at [address] and
[address–1]."

And this is exactly what's happening. It seems newer ARM cores are more
forgiving with such stuff.


So my question is this: This is not the compilers fault, correct? If
the user code were using array ops the unaligned save were detected,
but if they use pointer arithmetic there's nothing the compiler
could do?

Reply via email to