[arm-gnu] arm-none-eabi-gcc is generating code with ldm (load multiple) with unaligned accesses on ARMv7-M (m3)

richard.gibbs at calxeda.com richard.gibbs at calxeda.com
Tue Mar 6 16:28:09 UTC 2012


The above problem is causing a Hard Fault.  I can get around it by forcing full-word alignment of the array causing the problem.
 
arm-none-eabi-gcc --version reports:
 
arm-none-eabi-gcc (Sourcery CodeBench Lite 2011.09-69) 4.6.1
 
I'm cross-compiling on windows for armv7-m (m3) with the following cflags:
 
-mthumb -march=armv7-m -mfix-cortex-m3-ldrd -D__thumb -mno-thumb-interwork -mthumb -mcpu=cortex-m3
-Wall -Werr -Os -g -Wno-pointer-sign
 
The following describes how I get the problm:
 
1) I have a structure (first_struct) that in the middle, has an array of "char" (c).  Due to the preceeding fields in the structure, this array is on half-word alignment.  I have a second structure (second_struct) that has two ints (32-bit) at the top.
 
2) I have a function (first_function) that takes a void pointer as an argument, immediately assigns that argument to a structure pointer (so that it can reference the buffer as a structure), and references the first two fields (both full-word types).  For efficiency, the compiler generates an assembly instruction "ldi r0, {r4, r7}" to load the first two 32-bit values into registers.
 
3) A second_function passes a pointer to the array of "char" in first_struct to first_function.
 
4) When the LDM in step 2 (above) executes, I get a hard-fault, since the LDM requires full-word alignment of the address in (r0).
 
Is there a compile flag that will prevent this alignment problem, either in the initial structure layout, or by not using the ldm in target function for this case?
 
Example:
 
struct first_struct {
    char a;
    char b;
    char c[100];
}
 
struct second_struct {
     int x;
     int y;
}
 
void first_function(void *mystruct)
{
     struct second_struct *zz = (struct second_struct *) mystruct;
     int aaa;
     int bbb;
 
     aaa = zz->x;
     bbb = zz->y;
    
     .
     .
     .
}
 
void second_function(void)
{
     struct first_struct local;
 
     .
     .
     .
 
     memcpy (&local->c[0],SOME_ARRAY,sizeof(local->c));
     first_function(&local->c[0];
}
 
 
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/arm-gnu/attachments/20120306/35deeda7/attachment.html>


More information about the arm-gnu mailing list