From: Richard Earnshaw Date: Fri, 17 Oct 2003 14:45:47 +0000 (+0000) Subject: arm.c (use_return_insn): Not a single instruction, if there's a frame pointer. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=efc2515b4913b2b8870b041475542277520aa002;p=gcc.git arm.c (use_return_insn): Not a single instruction, if there's a frame pointer. * config/arm/arm.c (use_return_insn): Not a single instruction, if there's a frame pointer. (arm_output_epilogue): Protect stack pointer from being corrupted on interrupt. Co-Authored-By: Nathan Sidwell From-SVN: r72606 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2b8fc81911c..912074a9ea1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2003-10-17 Richard Earnshaw + Nathan Sidwell + + * config/arm/arm.c (use_return_insn): Not a single instruction, if + there's a frame pointer. + (arm_output_epilogue): Protect stack pointer from being corrupted + on interrupt. + 2003-10-17 Ulrich Weigand * ifcvt.c (noce_try_addcc): Handle ifs with 'else' case. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index dc8c5366536..70ea4cda89a 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -986,7 +986,11 @@ use_return_insn (int iscond) /* Never use a return instruction before reload has run. */ if (!reload_completed) return 0; - + + /* We need two instructions when there's a frame pointer. */ + if (frame_pointer_needed) + return 0; + func_type = arm_current_func_type (); /* Naked functions and volatile functions need special @@ -8500,8 +8504,18 @@ arm_output_epilogue (int really_return) saved_regs_mask &= ~ (1 << LR_REGNUM); else saved_regs_mask &= ~ (1 << PC_REGNUM); - - print_multi_reg (f, "ldmea\t%r", FP_REGNUM, saved_regs_mask); + + /* We must use SP as the base register, because SP is one of the + registers being restored. If an interrupt or page fault + happens in the ldm instruction, the SP might or might not + have been restored. That would be bad, as then SP will no + longer indicate the safe area of stack, and we can get stack + corruption. Using SP as the base register means that it will + be reset correctly to the original value, should an interrupt + occur. */ + asm_fprintf (f, "\tsub\t%r,%r,#%d\n", SP_REGNUM, FP_REGNUM, + 4 * bit_count (saved_regs_mask)); + print_multi_reg (f, "ldmfd\t%r", SP_REGNUM, saved_regs_mask); if (IS_INTERRUPT (func_type)) /* Interrupt handlers will have pushed the