[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