Epiphany - Double alignment issue

Any technical questions about the Epiphany chip and Parallella HW Platform.

Moderator: aolofsson

Epiphany - Double alignment issue

Postby heshamelmatary » Wed Nov 26, 2014 9:12 am

Hi,

I got some undesired behaviour with the compiler's generated code. It's said in the manual that structures and double words should be aligned to 8 bytes. I am makinh sure that the start if the stack is aligned to 8 bytes. Given that, some structures created within a function are not aligned to double-words, and subsequent read/write (which uses strd and ldrd instructions) accesses causes an exception to occur and hence the program hangs. Is there a compiler flag to force such a problem? Most of the flags like -malign-double -m64 are machine dependent (x86, sparc).

Regards,
Hesham
-- Hesham
heshamelmatary
 
Posts: 11
Joined: Thu Nov 13, 2014 3:31 pm
Location: UK

Re: Epiphany - Double alignment issue

Postby heshamelmatary » Wed Nov 26, 2014 6:05 pm

Digging into more details, the exact assembly store instruction that hangs the program is

ldrd r0,[fp,+0xc]
strd r0,[sp,+0xa] ;; here where it hangs

sp = 0x8effff04
fp = 0x8effff04
r0 = 0x0

Why fp is not aligned to 8 bytes? Given that the initial stack and fp address is "0x8EFFFF00" set at the linker script.
Some structures are not double-aligned when generated too, where I have to add __attribute__ ((align(8)));
Last edited by heshamelmatary on Thu Nov 27, 2014 1:08 pm, edited 1 time in total.
-- Hesham
heshamelmatary
 
Posts: 11
Joined: Thu Nov 13, 2014 3:31 pm
Location: UK

Re: Epiphany - Double alignment issue

Postby notzed » Thu Nov 27, 2014 2:55 am

Shouldn't the linker script setting up an 8-byte aligned stack to start with? The ABI requires that the stack is always 8-byte aligned so the compiler doesn't have to ever waste code aligning it.
notzed
 
Posts: 331
Joined: Mon Dec 17, 2012 12:28 am
Location: Australia

Re: Epiphany - Double alignment issue

Postby heshamelmatary » Thu Nov 27, 2014 9:34 am

Hi,

notzed wrote:Shouldn't the linker script setting up an 8-byte aligned stack to start with? The ABI requires that the stack is always 8-byte aligned so the compiler doesn't have to ever waste code aligning it.


The linker script already aligns the start of the stack to 8 bytes, but that's not enough. Structures must be aligned to 8 bytes, the compiler should be responsible for such an alignment, and it really does (theoretically). gcc/config/epiphany/apiphany.h has some macros to re-align data. Despite I define the start of the stack, and frame pointer, to a multiple af 8-bytes aligned address, the compiler generates some 4-byes aligned accesses, and sometimes set $fp to 4-bytes alignment, although it's said in the manual that it must be 8-bytes aligned. Moreover, I noticed that PARAM_BOUNDARY is defined to 32, why it's not 64? Structures passed as function arguments cause a write exception because it copies this content using ldrd/strd instructions.
-- Hesham
heshamelmatary
 
Posts: 11
Joined: Thu Nov 13, 2014 3:31 pm
Location: UK

Re: Epiphany - Double alignment issue

Postby notzed » Thu Nov 27, 2014 11:46 am

You should provide an example and the flags you use.
notzed
 
Posts: 331
Joined: Mon Dec 17, 2012 12:28 am
Location: Australia

Re: Epiphany - Double alignment issue

Postby heshamelmatary » Thu Nov 27, 2014 12:15 pm

notzed wrote:You should provide an example and the flags you use.


Sure.

The following is the snippet of code that causes the problem (compiled with -O0 -g flags):

Code: Select all
static void _Thread_Create_idle_for_cpu( Per_CPU_Control *cpu )
     27 {
     28   Thread_Control *idle;
     29   Objects_Name    name __attribute__ ((aligned(32)));
     30
     31   name.name_u32 = _Objects_Build_name( 'I', 'D', 'L', 'E' );
     32
     33   /*
     34    *  The entire workspace is zeroed during its initialization.  Thus, all
     35    *  fields not explicitly assigned were explicitly zeroed by
     36    *  _Workspace_Initialization.
     37    */
     38   idle = _Thread_Internal_allocate();
     39
     40   _Thread_Initialize(
     41     &_Thread_Internal_information,
     42     idle,
     43     _Scheduler_Get_by_CPU( cpu ),
     44     NULL,        /* allocate the stack */
     45     _Stack_Ensure_minimum( rtems_configuration_get_idle_task_stack_size() ),
     46     CPU_IDLE_TASK_IS_FP,
     47     PRIORITY_MAXIMUM,
     48     true,        /* preemptable */
     49     THREAD_CPU_BUDGET_ALGORITHM_NONE,
     50     NULL,        /* no budget algorithm callout */
     51     0,           /* all interrupts enabled */
     52     name
     53   );


The specific line that causes the problem is line 52, where the "name" structure is copied to the stack as a _Thread_Initialize function argument.

The assembly instructions of loading/storing this "name" structure are:

Code: Select all
8e01452c: 1064        ldrd r0,[r4]
8e01452e: 157c 0401   strd r0,[sp,+0xa]


sp at this point is equal to 0x8effffee4, given that, strd r0,[sp,+0xa] would rise a write exception because the store address is not double-word aligned! This is definitely a matter of the compiler. I think it relates to PARAM_BOUNDARY macro at gcc/config/epiphany/epiphany.h which is defined to 32. Hope this use case/example is enough.

Thanks,
Hesham
-- Hesham
heshamelmatary
 
Posts: 11
Joined: Thu Nov 13, 2014 3:31 pm
Location: UK


Return to Epiphany and Parallella Q & A

Who is online

Users browsing this forum: No registered users and 13 guests

cron