From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3735 invoked by alias); 7 Feb 2008 13:55:01 -0000 Received: (qmail 3607 invoked by uid 48); 7 Feb 2008 13:54:15 -0000 Date: Thu, 07 Feb 2008 13:55:00 -0000 Message-ID: <20080207135415.3606.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug target/16634] arm-elf-gcc problems when generating code for __attribute__ ((interrupt ("IRQ"))) In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "mmz at gmx dot net" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2008-02/txt/msg00824.txt.bz2 ------- 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