------- Comment #10 from mmz at gmx dot net 2008-02-07 13:54 -------
(In reply to comment #9)
> is this bug still present in 4.2.2?
I can confirm this bug still exists in 4.2.2 and 4.2.3.
> Acc. to my obervations the error only shows up when not all auto variables can
> be mapped to registers, and additional variables are located on stack. As a
> work-around, if a more complex interrupt handler is needed, place the code in
> a
> subfunction and call this function from the interrupt handler. In this case no
> stack is reserved in the interrupt handler, and the generated code is OK. Care
> must be taken, of course, that the optimizer does not inline the code for
> IntFunc().
Your subfunction workaround actually did the trick. The generated return
instruction is "ldm sp!, {r0, r1, r2, r3, ip, pc}^". However, if a more complex
interrupt handler is implemented the wrong return instruction generated. The
results seem a bit unpredictable so I currently use plain assembler for my
interrupts.
Example:
extern __attribute__ ((interrupt ("IRQ"))) void
base_int_ctrl_top_irq_handler(void)
{
int_ctrl_status_t status;
status.val = READ_REG_U32(ADDR_STATUS_NIRQ);
if (status.bf.x) {
puts("Spurious x IRQ!");
} else if (status.bf.y) {
puts("Spurious y IRQ!");
} else if (status.bf.timer) {
base_timer_interrupt();
} else if (status.bf.z) {
puts("Spurious z IRQ!");
} else {
puts("Spurious unknown IRQ!");
}
}
Generated assembly for return:
pop {r0, r1, r2, r3, ip, lr}
subs pc, lr, #4 ; 0x4
(and lr was already decremented by 4 when the handler was entered)
So your observations are correct.
Bug #27859 seems to be a duplicate of this bug and contains a patch. However,
this patch is probably not optimal since it just replaces the final "subs" by a
"movs" while the best solution seems to be the "ldmfd ..." instruction above.
--
mmz at gmx dot net changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |mmz at gmx dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16634