From: Nick Clifton <nickc@redhat.com>
To: "Ge Ming Dong" <dong_geming@hotmail.com>
CC: Richard.Earnshaw@arm.com, gcc-patches@gcc.gnu.org,
jean-marc.koller@csem.ch, tori@unhappy.mine.nu
Subject: Re: GCC 3.3 for ARM Bug ???
Date: Mon, 19 May 2003 12:29:08 +0100
Hi Ge Ming Dong,
> I cmopiled the following file with gcc 3.3 for ARM (It was just
released).
>
> /* begin of file ext_irq.c */
> void ext_IRQ0_handler(void) __attribute__ ((interrupt ("IRQ")));
> void ext_IRQ0_handler(void)
> {
> int i = 0;
> i = i++;
> }
> /* end of file ext_irq.c */
>
> If it was Compiled with the following command:
> arm-elf-gcc -gdwarf ext_irq.c -o.\debug\ext_irq.o
> then Dump the ext_irq.o, and we can get the following code:
>
> 00000000 <ext_IRQ0_handler>:
> 0: e52dc004 str ip, [sp, -#4]!
> 4: e1a0c00d mov ip, sp
> 8: e24ee004 sub lr, lr, #4 ; 0x4
> c: e92dd80e stmdb sp!, {r1, r2, r3, fp, ip, lr, pc}
[snip]
> 38: e95b980e ldmdb fp, {r1, r2, r3, fp, ip, pc}^
> Would you pls answer me ASAP?
The gcc 3.3 branch is missing this patch, which has been applied to
the mainline sources:
2003-01-24 Nick Clifton <nickc@redhat.com>
* config/arm/arm.c (use_return_insn): Do not use a single return
instruction for interrupt handlers which have to create a stack
frame.
(arm_expand_prologue): Do not pre-bias the return address of
interrupt handlers which create a stack frame.
I will apply the patch myself.
Cheers
Nick
Index: gcc/config/arm/arm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.243.2.2
diff -c -3 -p -w -r1.243.2.2 arm.c
*** gcc/config/arm/arm.c 20 Feb 2003 16:59:02 -0000 1.243.2.2
--- gcc/config/arm/arm.c 19 May 2003 11:19:44 -0000
*************** use_return_insn (iscond)
*** 922,927 ****
--- 922,931 ----
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 ()
*** 8467,8484 ****
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)
{
--- 8471,8489 ----
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)
{