Index: config/arm/arm-protos.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/arm/arm-protos.h,v retrieving revision 1.35 diff -c -r1.35 arm-protos.h *** config/arm/arm-protos.h 20 Oct 2002 22:37:08 -0000 1.35 --- config/arm/arm-protos.h 4 Nov 2002 23:25:53 -0000 *************** *** 31,36 **** --- 31,37 ---- extern int arm_volatile_func PARAMS ((void)); extern const char * arm_output_epilogue PARAMS ((int)); extern void arm_expand_prologue PARAMS ((void)); + extern HOST_WIDE_INT arm_get_frame_size PARAMS ((void)); /* Used in arm.md, but defined in output.c. */ extern void assemble_align PARAMS ((int)); extern const char * arm_strip_name_encoding PARAMS ((const char *)); *************** *** 160,165 **** --- 161,167 ---- extern void arm_init_expanders PARAMS ((void)); extern int thumb_far_jump_used_p PARAMS ((int)); extern const char * thumb_unexpanded_epilogue PARAMS ((void)); + extern HOST_WIDE_INT thumb_get_frame_size PARAMS ((void)); extern void thumb_expand_prologue PARAMS ((void)); extern void thumb_expand_epilogue PARAMS ((void)); #ifdef TREE_CODE Index: config/arm/arm.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v retrieving revision 1.240 diff -c -r1.240 arm.c *** config/arm/arm.c 1 Nov 2002 14:41:57 -0000 1.240 --- config/arm/arm.c 4 Nov 2002 23:26:01 -0000 *************** *** 928,934 **** /* 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. */ ! || ((get_frame_size () + current_function_outgoing_args_size != 0) && !frame_pointer_needed)) return 0; --- 928,934 ---- /* 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; *************** *** 7564,7570 **** frame that is $fp + 4 for a non-variadic function. */ int floats_offset = 0; rtx operands[3]; ! int frame_size = get_frame_size (); FILE * f = asm_out_file; rtx eh_ofs = cfun->machine->eh_epilogue_sp_ofs; --- 7564,7570 ---- frame that is $fp + 4 for a non-variadic function. */ int floats_offset = 0; rtx operands[3]; ! int frame_size = arm_get_frame_size (); FILE * f = asm_out_file; rtx eh_ofs = cfun->machine->eh_epilogue_sp_ofs; *************** *** 7846,7851 **** --- 7846,7854 ---- } else { + /* We need to take into account any stack-frame rounding. */ + frame_size = arm_get_frame_size (); + if (use_return_insn (FALSE) && return_used_this_function && (frame_size + current_function_outgoing_args_size) != 0 *************** *** 8088,8094 **** unsigned int from; unsigned int to; { ! unsigned int local_vars = (get_frame_size () + 3) & ~3; unsigned int outgoing_args = current_function_outgoing_args_size; unsigned int stack_frame; unsigned int call_saved_registers; --- 8091,8097 ---- unsigned int from; unsigned int to; { ! unsigned int local_vars = arm_get_frame_size (); unsigned int outgoing_args = current_function_outgoing_args_size; unsigned int stack_frame; unsigned int call_saved_registers; *************** *** 8209,8214 **** --- 8212,8266 ---- } } + /* Calculate the size of the stack frame, taking into account any + padding that is required to ensure stack-alignment. */ + + HOST_WIDE_INT + arm_get_frame_size () + { + int regno; + + int base_size = ROUND_UP (get_frame_size ()); + int entry_size = 0; + int save_regs_mask; + unsigned long func_type = arm_current_func_type (); + + if (! TARGET_ARM) + abort(); + + if (! TARGET_ATPCS) + return base_size; + + /* We know that SP will be word aligned on entry, and we must + preserve that condition at any subroutine call. But those are + the only constraints. */ + + /* Space for variadic functions. */ + if (current_function_pretend_args_size) + entry_size += current_function_pretend_args_size; + + /* Space for saved registers. */ + save_regs_mask = arm_compute_save_reg_mask (); + for (regno = 0; regno <= LAST_ARM_REGNUM; regno++) + if (save_regs_mask & (1 << regno)) + entry_size += 4; + + /* Space for saved FPA registers. */ + if (! IS_VOLATILE (func_type)) + { + for (regno = FIRST_ARM_FP_REGNUM; regno <= LAST_ARM_FP_REGNUM; regno++) + if (regs_ever_live[regno] && ! call_used_regs[regno]) + entry_size += 12; + } + + if ((entry_size + base_size + current_function_outgoing_args_size) & 7) + base_size += 4; + if ((entry_size + base_size + current_function_outgoing_args_size) & 7) + abort (); + + return base_size; + } + /* Generate the prologue instructions for entry into an ARM function. */ void *************** *** 8444,8450 **** } } ! amount = GEN_INT (-(get_frame_size () + current_function_outgoing_args_size)); if (amount != const0_rtx) --- 8496,8502 ---- } } ! amount = GEN_INT (-(arm_get_frame_size () + current_function_outgoing_args_size)); if (amount != const0_rtx) *************** *** 10193,10204 **** init_machine_status = arm_init_machine_status; } /* Generate the rest of a function's prologue. */ void thumb_expand_prologue () { ! HOST_WIDE_INT amount = (get_frame_size () + current_function_outgoing_args_size); unsigned long func_type; --- 10245,10314 ---- init_machine_status = arm_init_machine_status; } + HOST_WIDE_INT + thumb_get_frame_size () + { + int regno; + + int base_size = ROUND_UP (get_frame_size ()); + int count_regs = 0; + int entry_size = 0; + + if (! TARGET_THUMB) + abort (); + + if (! TARGET_ATPCS) + return base_size; + + /* We know that SP will be word aligned on entry, and we must + preserve that condition at any subroutine call. But those are + the only constraints. */ + + /* Space for variadic functions. */ + if (current_function_pretend_args_size) + entry_size += current_function_pretend_args_size; + + /* Space for pushed lo registers. */ + for (regno = 0; regno <= LAST_LO_REGNUM; regno++) + if (THUMB_REG_PUSHED_P (regno)) + count_regs++; + + /* Space for backtrace structure. */ + if (TARGET_BACKTRACE) + { + if (count_regs == 0 && regs_ever_live[LAST_ARG_REGNUM] != 0) + entry_size += 20; + else + entry_size += 16; + } + + if (count_regs || !leaf_function_p () || thumb_far_jump_used_p (1)) + count_regs++; /* LR */ + + entry_size += count_regs * 4; + count_regs = 0; + + /* Space for pushed hi regs. */ + for (regno = 8; regno < 13; regno++) + if (THUMB_REG_PUSHED_P (regno)) + count_regs++; + + entry_size += count_regs * 4; + + if ((entry_size + base_size + current_function_outgoing_args_size) & 7) + base_size += 4; + if ((entry_size + base_size + current_function_outgoing_args_size) & 7) + abort (); + + return base_size; + } + /* Generate the rest of a function's prologue. */ void thumb_expand_prologue () { ! HOST_WIDE_INT amount = (thumb_get_frame_size () + current_function_outgoing_args_size); unsigned long func_type; *************** *** 10293,10299 **** void thumb_expand_epilogue () { ! HOST_WIDE_INT amount = (get_frame_size () + current_function_outgoing_args_size); /* Naked functions don't have prologues. */ --- 10403,10409 ---- void thumb_expand_epilogue () { ! HOST_WIDE_INT amount = (thumb_get_frame_size () + current_function_outgoing_args_size); /* Naked functions don't have prologues. */ Index: config/arm/arm.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.h,v retrieving revision 1.166 diff -c -r1.166 arm.h *** config/arm/arm.h 20 Oct 2002 22:37:09 -0000 1.166 --- config/arm/arm.h 4 Nov 2002 23:26:03 -0000 *************** *** 689,694 **** --- 689,696 ---- #define STACK_BOUNDARY 32 + #define PREFERRED_STACK_BOUNDARY (TARGET_ATPCS ? 64 : 32) + #define FUNCTION_BOUNDARY 32 /* The lowest bit is used to indicate Thumb-mode functions, so the *************** *** 1679,1685 **** if ((TO) == STACK_POINTER_REGNUM) \ { \ (OFFSET) += current_function_outgoing_args_size; \ ! (OFFSET) += ROUND_UP (get_frame_size ()); \ } \ } --- 1681,1687 ---- if ((TO) == STACK_POINTER_REGNUM) \ { \ (OFFSET) += current_function_outgoing_args_size; \ ! (OFFSET) += thumb_get_frame_size (); \ } \ }