Index: arm.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v retrieving revision 1.303 diff -p -r1.303 arm.c *** arm.c 24 Oct 2003 09:25:30 -0000 1.303 --- arm.c 28 Oct 2003 09:38:28 -0000 *************** use_return_insn (int iscond) *** 1015,1024 **** 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 --- 1015,1020 ---- *************** use_return_insn (int iscond) *** 1033,1043 **** /* As do variadic functions. */ if (current_function_pretend_args_size || cfun->machine->uses_anonymous_args ! /* Of if the function calls __builtin_eh_return () */ || ARM_FUNC_TYPE (func_type) == ARM_FT_EXCEPTION_HANDLER ! /* Or if there is no frame pointer and there is a stack adjustment. */ ! || ((arm_get_frame_size () + current_function_outgoing_args_size != 0) ! && !frame_pointer_needed)) return 0; saved_int_regs = arm_compute_save_reg_mask (); --- 1029,1040 ---- /* As do variadic functions. */ if (current_function_pretend_args_size || cfun->machine->uses_anonymous_args ! /* Or if the function calls __builtin_eh_return () */ || ARM_FUNC_TYPE (func_type) == ARM_FT_EXCEPTION_HANDLER ! /* Or if the function calls alloca */ ! || current_function_calls_alloca ! /* Or if there is a stack adjustment. */ ! || (arm_get_frame_size () + current_function_outgoing_args_size != 0)) return 0; saved_int_regs = arm_compute_save_reg_mask (); *************** arm_compute_save_reg_mask (void) *** 8098,8104 **** return save_reg_mask; } ! /* Generate a function exit sequence. If REALLY_RETURN is true, then do everything bar the final return instruction. */ const char * output_return_instruction (rtx operand, int really_return, int reverse) --- 8163,8169 ---- return save_reg_mask; } ! /* Generate a function exit sequence. If REALLY_RETURN is false, then do everything bar the final return instruction. */ const char * output_return_instruction (rtx operand, int really_return, int reverse) *************** output_return_instruction (rtx operand, *** 8116,8123 **** if (IS_VOLATILE (func_type) && TARGET_ABORT_NORETURN) { ! /* If this function was declared non-returning, and we have found a tail ! call, then we have to trust that the called function won't return. */ if (really_return) { rtx ops[2]; --- 8181,8189 ---- if (IS_VOLATILE (func_type) && TARGET_ABORT_NORETURN) { ! /* If this function was declared non-returning, and we have ! found a tail call, then we have to trust that the called ! function won't return. */ if (really_return) { rtx ops[2]; *************** output_return_instruction (rtx operand, *** 8189,8198 **** char *p; int first = 1; ! /* Generate the load multiple instruction to restore the registers. */ ! if (frame_pointer_needed) ! sprintf (instr, "ldm%sea\t%%|fp, {", conditional); ! else if (live_regs_mask & (1 << SP_REGNUM)) sprintf (instr, "ldm%sfd\t%%|sp, {", conditional); else sprintf (instr, "ldm%sfd\t%%|sp!, {", conditional); --- 8255,8265 ---- char *p; int first = 1; ! /* Generate the load multiple instruction to restore the ! registers. Note we can get here, even if ! frame_pointer_needed is true, but only if sp already ! points to the base of the saved core registers. */ ! if (live_regs_mask & (1 << SP_REGNUM)) sprintf (instr, "ldm%sfd\t%%|sp, {", conditional); else sprintf (instr, "ldm%sfd\t%%|sp!, {", conditional); *************** arm_output_epilogue (int really_return) *** 8552,8560 **** 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)) --- 8619,8631 ---- 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. If the stack pointer already points at the right ! place, then omit the subtraction. */ ! if (((frame_size + current_function_outgoing_args_size + floats_offset) ! != 4 * (1 + (int) bit_count (saved_regs_mask))) ! || current_function_calls_alloca) ! 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))