cgccarmgcc8

arm 32 byte move with ldm/stm as inline asm


I am trying to do the following and it doesnt work. The code crash with an arm toolchain gcc 8.5.

#define _move(src, dst) __asm volatile ( \
                "ldr   r0, [%0] \n\t"    \
                "ldr   r1, [%1] \n\t"    \
                "ldm   r0!, {r4-r11} \n\t" \
                "stm   r1!, {r4-r11} \n\t" \
                :          \
                : "r" (dst), "r" (src)          \
                : "cc"          \
                )


static uint32_t sr[8];
static uint32_t ds[8];

int main() {

    sr[0] = 0xff;
    
    _move(sr, ds);

    printf("data:%d\n", ds[0]);

}

What is wrong with the code?

https://godbolt.org/z/edzz9vhPK


Solution

  • The problem was an unaligned access because in the real project there is a buffer which starts aligned 32 but the access with ldm to the data was sometimes unaligned.

    Now I check the src pointer before accessing them and if it is not aligned I mask the first two bits out. At the time I process the data this is checked and corrected.