[cfe-users] ARM fast interrupt handlers

Arnaud A. de Grandmaison arnaud.degrandmaison at arm.com
Wed Mar 4 00:09:05 PST 2015


Oops. Forgot to CC cfe-users.

> -----Original Message-----
> From: Arnaud A. de Grandmaison [mailto:arnaud.degrandmaison at arm.com]
> Sent: 03 March 2015 22:35
> To: 'Sven Köhler'
> Subject: RE: [cfe-users] ARM fast interrupt handlers
> 
> Hi Sven,
> 
> I suggest you create a bug report for this at http://llvm.org/bugs/
> 
> The bfc instruction is there for clearing the stack pointer lsb,
effectively
> realigning the stack. I however do not see why this is necessary as the
stack is
> not used.
> 
> Regards,
> --
> Arnaud
> 
> > -----Original Message-----
> > From: cfe-users-bounces at cs.uiuc.edu [mailto:cfe-users-
> > bounces at cs.uiuc.edu] On Behalf Of Sven Köhler
> > Sent: 02 March 2015 18:40
> > To: cfe-users at cs.uiuc.edu
> > Subject: [cfe-users] ARM fast interrupt handlers
> >
> > Hi,
> >
> > clang/llvm 3.5 was generating bad assembly code for FIQ interrupt
> > handlers when optimization was enabled. Now with llvm 3.6 the
> > generated assembly seems to be working, but it's somewhat suboptimal.
> >
> > If this is not the right place to discuss, please let me know what
> > might be a better place.
> >
> > First consider this C-code:
> >
> > int* global;
> >
> > __attribute__((interrupt("IRQ")))
> > void irq() {
> >   *global++ = 1;
> > }
> >
> > __attribute__((interrupt("FIQ")))
> > void fiq() {
> >   *global++ = 1;
> > }
> >
> > I'm generating the assembly like this:
> > clang --target=armv7-linux-gnu -mfloat-abi=hard -O2 -S
> >
> > With llvm 3.5.0 I got severely broken code for fiq():
> >
> > fiq:
> > 	movw	r8, :lower16:global
> > 	subs	pc, lr, #4
> > 	movt	r8, :upper16:global
> > 	ldr	r9, [r8]
> > 	add	r10, r9, #4
> > 	str	r10, [r8]
> > 	mov	r8, #1
> > 	str	r8, [r9]
> >
> > The jump that exits the function basically was "optimized" to the
> > beginning of the function. The resulting could would basically not do
> > anything. With - O0, the generated assembly was fine.
> >
> > Now with llvm 3.6.0, the code is a bit more "lengthy" but correct:
> >
> > fiq:
> > 	push	{r11}
> > 	mov	r11, sp
> > 	sub	sp, sp, #4
> > 	bfc	sp, #0, #3
> > 	movw	r8, :lower16:global
> > 	movt	r8, :upper16:global
> > 	ldr	r9, [r8]
> > 	add	r10, r9, #4
> > 	str	r10, [r8]
> > 	mov	r8, #1
> > 	str	r8, [r9]
> > 	mov	sp, r11
> > 	pop	{r11}
> > 	subs	pc, lr, #4
> >
> > For some reason, clang sets up the frame pointer register (r11). All
> > of the code busy with managing r11 could be omitted. Not sure what the
> > bfc command does. Does it try to round down sp to a multiple of four?
> > Even though the stack has already been used by the push? Push probably
> > doesn't support unaligned access. And sp is actually never ever used.
> >
> > The assembly generated for irq() is somewhat similar. Only the
> > assembly generated for normal() doesn't bother about r11 and looks quite
> optimal.
> >
> > I tried using -fomit-frame-pointer, but it didn't improve the assembly.
> >
> >
> > Any ideas what's going on?
> >
> >
> > Regards,
> >   Sven
> >
> > _______________________________________________
> > cfe-users mailing list
> > cfe-users at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-users








More information about the cfe-users mailing list