From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11008 invoked by alias); 23 Jan 2003 10:37:46 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 10998 invoked from network); 23 Jan 2003 10:37:43 -0000 Received: from unknown (HELO fencepost.gnu.org) (199.232.76.164) by 172.16.49.205 with SMTP; 23 Jan 2003 10:37:43 -0000 Received: from monty-python.gnu.org ([199.232.76.173]) by fencepost.gnu.org with esmtp (Exim 4.10) id 18bejv-0001vX-00 for gcc@gnu.org; Thu, 23 Jan 2003 05:37:43 -0500 Received: from mail by monty-python.gnu.org with spam-scanned (Exim 4.10.13) id 18bejp-0001Yw-00 for gcc@gnu.org; Thu, 23 Jan 2003 05:37:38 -0500 Received: from mx1.redhat.com ([66.187.233.31]) by monty-python.gnu.org with esmtp (Exim 4.10.13) id 18beix-0000mA-00 for gcc@gnu.org; Thu, 23 Jan 2003 05:36:43 -0500 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.11.6/8.11.6) with ESMTP id h0NA7lf14806; Thu, 23 Jan 2003 05:07:47 -0500 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [172.16.52.156]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id h0NAafa27791; Thu, 23 Jan 2003 05:36:41 -0500 Received: from north-pole.nickc.cambridge.redhat.com.redhat.com (vpn50-6.rdu.redhat.com [172.16.50.6]) by pobox.corp.redhat.com (8.11.6/8.11.6) with ESMTP id h0NAab211654; Thu, 23 Jan 2003 05:36:39 -0500 To: Eric de Jong Cc: gcc@gnu.org, ericdejong@gmx.net Subject: Re: ARM interrupts References: <20030122155635.72386.qmail@web40104.mail.yahoo.com> From: Nick Clifton Date: Thu, 23 Jan 2003 18:08:00 -0000 In-Reply-To: <20030122155635.72386.qmail@web40104.mail.yahoo.com> Message-ID: User-Agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/21.1 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Spam-Status: No, hits=-11.8 required=5.0 tests=IN_REP_TO,PATCH_CONTEXT_DIFF,QUOTED_EMAIL_TEXT,REFERENCES, SPAM_PHRASE_00_01,USER_AGENT version=2.41 X-Spam-Level: X-SW-Source: 2003-01/txt/msg01047.txt.bz2 Hi Eric, > When I compile the following c program: > > void at91_default_irq_handler() __attribute__ ((interrupt ("FIQ"))); > void at91_default_irq_handler() {} > > Then I get the following assembly code: > > entry code: > 1) str ip, [sp, #-4]! > 2) mov ip, sp > 3) sub lr, lr, #4 > 4) stmfd sp!, {fp, ip, lr, pc} > 5) sub fp, ip, #4 > 6) ldmea fp, {fp, ip, pc}^ > Who can explain this? It is a bug in the compiler. Gcc thought that it was able to use a single instruction to return from the interrupt handler. It had forgotten to allow for the fact that IP had to be pushed before the stack frame could be created. Please try applying the following patch to your sources and rebuilding gcc. It should fix the problem. Cheers Nick 2003-01-23 Nick Clifton * config/arm/arm.c (use_return_insn): Do not allow interrupt handlers with a stack frame to use a single instruction return - they need to pop the IP register. (arm_expand_prologue): Do not pre-bias the LR register for interrupt handlers unless they are going to use a single instruction return. Index: gcc/config/arm/arm.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v retrieving revision 1.247 diff -c -3 -p -w -r1.247 arm.c *** gcc/config/arm/arm.c 22 Jan 2003 16:01:42 -0000 1.247 --- gcc/config/arm/arm.c 23 Jan 2003 10:31:33 -0000 *************** use_return_insn (iscond) *** 935,940 **** --- 935,944 ---- if (func_type & (ARM_FT_VOLATILE | ARM_FT_NAKED)) return 0; + /* So do interrupt functions that use the frame pointer. */ + if (IS_INTERRUPT (func_type) && frame_pointer_needed) + return 0; + /* As do variadic functions. */ if (current_function_pretend_args_size || cfun->machine->uses_anonymous_args *************** arm_expand_prologue () *** 8639,8656 **** RTX_FRAME_RELATED_P (insn) = 1; } ! /* If this is an interrupt service routine, and the link register is ! going to be pushed, subtracting four now will mean that the ! function return can be done with a single instruction. */ if ((func_type == ARM_FT_ISR || func_type == ARM_FT_FIQ) ! && (live_regs_mask & (1 << LR_REGNUM)) != 0) ! { emit_insn (gen_rtx_SET (SImode, gen_rtx_REG (SImode, LR_REGNUM), gen_rtx_PLUS (SImode, gen_rtx_REG (SImode, LR_REGNUM), GEN_INT (-4)))); - } if (live_regs_mask) { --- 8643,8661 ---- RTX_FRAME_RELATED_P (insn) = 1; } ! /* If this is an interrupt service routine, and the link register ! is going to be pushed, and we are not creating a stack frame, ! (which would involve an extra push of IP and a pop in the epilogue) ! subtracting four from LR now will mean that the function return ! can be done with a single instruction. */ if ((func_type == ARM_FT_ISR || func_type == ARM_FT_FIQ) ! && (live_regs_mask & (1 << LR_REGNUM)) != 0 ! && ! frame_pointer_needed) emit_insn (gen_rtx_SET (SImode, gen_rtx_REG (SImode, LR_REGNUM), gen_rtx_PLUS (SImode, gen_rtx_REG (SImode, LR_REGNUM), GEN_INT (-4)))); if (live_regs_mask) {