From: Olivier Hainque Date: Tue, 11 Aug 2009 05:14:48 +0000 (+0000) Subject: alpha.c (alpha_sa_size): Force procedure type to PT_STACK when frame_pointer_needed... X-Git-Tag: releases/gcc-4.5.0~4092 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1d3499d85c4948d5c5f63353f883e3e9f03ac470;p=thirdparty%2Fgcc.git alpha.c (alpha_sa_size): Force procedure type to PT_STACK when frame_pointer_needed on OpenVMS. * config/alpha/alpha.c (alpha_sa_size): Force procedure type to PT_STACK when frame_pointer_needed on OpenVMS. (alpha_pv_save_size, alpha_using_fp): Remove. (alpha_vms_can_eliminate): New function. Support for CAN_ELIMINATE with proper processing for PT_NULL. (alpha_vms_initial_elimination_offset): New function. Support for INITIAL_ELIMINATION_OFFSET with proper processing for PT_NULL. (alpha_sa_size): Force procedure type to PT_STACK when frame_pointer_needed on OpenVMS. * config/alpha/alpha-protos.h (alpha_pv_save_size): Remove prototype. (alpha_using_fp): Likewise. (alpha_vms_can_eliminate): Add prototype. (alpha_vms_initial_elimination_offset): Likewise. * config/alpha/vms.h (CAN_ELIMINATE, INITIAL_ELIMINATION_OFFSET): Call alpha_vms_can_eliminate and alpha_vms_initial_elimination_offset. Co-Authored-By: Douglas B Rupp From-SVN: r150646 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 17d7f63816ba..d15941a38bc3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2009-08-10 Olivier Hainque + Douglas B Rupp + + * config/alpha/alpha.c (alpha_sa_size): Force procedure type to + PT_STACK when frame_pointer_needed on OpenVMS. + (alpha_pv_save_size, alpha_using_fp): Remove. + (alpha_vms_can_eliminate): New function. Support for CAN_ELIMINATE + with proper processing for PT_NULL. + (alpha_vms_initial_elimination_offset): New function. Support for + INITIAL_ELIMINATION_OFFSET with proper processing for PT_NULL. + (alpha_sa_size): Force procedure type to PT_STACK when + frame_pointer_needed on OpenVMS. + * config/alpha/alpha-protos.h (alpha_pv_save_size): Remove prototype. + (alpha_using_fp): Likewise. + (alpha_vms_can_eliminate): Add prototype. + (alpha_vms_initial_elimination_offset): Likewise. + * config/alpha/vms.h (CAN_ELIMINATE, INITIAL_ELIMINATION_OFFSET): + Call alpha_vms_can_eliminate and alpha_vms_initial_elimination_offset. + 2009-08-10 Eric Botcazou Douglas B Rupp diff --git a/gcc/config/alpha/alpha-protos.h b/gcc/config/alpha/alpha-protos.h index 39091b7fd312..43665d3af20f 100644 --- a/gcc/config/alpha/alpha-protos.h +++ b/gcc/config/alpha/alpha-protos.h @@ -28,8 +28,6 @@ extern int direct_return (void); extern int alpha_sa_size (void); extern HOST_WIDE_INT alpha_initial_elimination_offset (unsigned int, unsigned int); -extern int alpha_pv_save_size (void); -extern int alpha_using_fp (void); extern void alpha_expand_prologue (void); extern void alpha_expand_epilogue (void); extern void alpha_output_filename (FILE *, const char *); @@ -116,7 +114,9 @@ extern void avms_asm_output_external (FILE *, tree, const char *); extern void vms_output_aligned_decl_common (FILE *, tree, const char *, unsigned HOST_WIDE_INT, unsigned int); - +extern int alpha_vms_can_eliminate (unsigned int, unsigned int); +extern HOST_WIDE_INT alpha_vms_initial_elimination_offset (unsigned int, + unsigned int); #endif extern rtx unicosmk_add_call_info_word (rtx); diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 84c2b7ce4200..a1ec73630bf7 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -7353,10 +7353,10 @@ alpha_sa_size (void) } else if (TARGET_ABI_OPEN_VMS) { - /* Start by assuming we can use a register procedure if we don't - make any calls (REG_RA not used) or need to save any - registers and a stack procedure if we do. */ - if ((mask[0] >> REG_RA) & 1) + /* Start with a stack procedure if we make any calls (REG_RA used), or + need a frame pointer, with a register procedure if we otherwise need + at least a slot, and with a null procedure in other cases. */ + if ((mask[0] >> REG_RA) & 1 || frame_pointer_needed) alpha_procedure_type = PT_STACK; else if (get_frame_size() != 0) alpha_procedure_type = PT_REGISTER; @@ -7446,21 +7446,96 @@ alpha_initial_elimination_offset (unsigned int from, return ret; } +#if TARGET_ABI_OPEN_VMS + int -alpha_pv_save_size (void) +alpha_vms_can_eliminate (unsigned int from ATTRIBUTE_UNUSED, unsigned int to) { + /* We need the alpha_procedure_type to decide. Evaluate it now. */ alpha_sa_size (); - return alpha_procedure_type == PT_STACK ? 8 : 0; + + switch (alpha_procedure_type) + { + case PT_NULL: + /* NULL procedures have no frame of their own and we only + know how to resolve from the current stack pointer. */ + return to == STACK_POINTER_REGNUM; + + case PT_REGISTER: + case PT_STACK: + /* We always eliminate except to the stack pointer if there is no + usable frame pointer at hand. */ + return (to != STACK_POINTER_REGNUM + || vms_unwind_regno != HARD_FRAME_POINTER_REGNUM); + } + + gcc_unreachable (); } -int -alpha_using_fp (void) -{ - alpha_sa_size (); - return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM; +/* FROM is to be eliminated for TO. Return the offset so that TO+offset + designates the same location as FROM. */ + +HOST_WIDE_INT +alpha_vms_initial_elimination_offset (unsigned int from, unsigned int to) +{ + /* The only possible attempts we ever expect are ARG or FRAME_PTR to + HARD_FRAME or STACK_PTR. We need the alpha_procedure_type to decide + on the proper computations and will need the register save area size + in most cases. */ + + HOST_WIDE_INT sa_size = alpha_sa_size (); + + /* PT_NULL procedures have no frame of their own and we only allow + elimination to the stack pointer. This is the argument pointer and we + resolve the soft frame pointer to that as well. */ + + if (alpha_procedure_type == PT_NULL) + return 0; + + /* For a PT_STACK procedure the frame layout looks as follows + + -----> decreasing addresses + + < size rounded up to 16 | likewise > + --------------#------------------------------+++--------------+++-------# + incoming args # pretended args | "frame" | regs sa | PV | outgoing args # + --------------#---------------------------------------------------------# + ^ ^ ^ ^ + ARG_PTR FRAME_PTR HARD_FRAME_PTR STACK_PTR + + + PT_REGISTER procedures are similar in that they may have a frame of their + own. They have no regs-sa/pv/outgoing-args area. + + We first compute offset to HARD_FRAME_PTR, then add what we need to get + to STACK_PTR if need be. */ + + { + HOST_WIDE_INT offset; + HOST_WIDE_INT pv_save_size = alpha_procedure_type == PT_STACK ? 8 : 0; + + switch (from) + { + case FRAME_POINTER_REGNUM: + offset = ALPHA_ROUND (sa_size + pv_save_size); + break; + case ARG_POINTER_REGNUM: + offset = (ALPHA_ROUND (sa_size + pv_save_size + + get_frame_size () + + crtl->args.pretend_args_size) + - crtl->args.pretend_args_size); + break; + default: + gcc_unreachable (); + } + + if (to == STACK_POINTER_REGNUM) + offset += ALPHA_ROUND (crtl->outgoing_args_size); + + return offset; + } } -#if TARGET_ABI_OPEN_VMS #define COMMON_OBJECT "common_object" static tree diff --git a/gcc/config/alpha/vms.h b/gcc/config/alpha/vms.h index fa7e3c2f9766..d8d513e07c84 100644 --- a/gcc/config/alpha/vms.h +++ b/gcc/config/alpha/vms.h @@ -144,27 +144,12 @@ along with GCC; see the file COPYING3. If not see #undef CAN_ELIMINATE #define CAN_ELIMINATE(FROM, TO) \ -((TO) != STACK_POINTER_REGNUM || ! alpha_using_fp ()) + (alpha_vms_can_eliminate ((FROM), (TO))) #undef INITIAL_ELIMINATION_OFFSET #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \ -{ switch (FROM) \ - { \ - case FRAME_POINTER_REGNUM: \ - (OFFSET) = alpha_sa_size () + alpha_pv_save_size (); \ - break; \ - case ARG_POINTER_REGNUM: \ - (OFFSET) = (ALPHA_ROUND (alpha_sa_size () + alpha_pv_save_size () \ - + get_frame_size () \ - + crtl->args.pretend_args_size) \ - - crtl->args.pretend_args_size); \ - break; \ - default: \ - gcc_unreachable (); \ - } \ - if ((TO) == STACK_POINTER_REGNUM) \ - (OFFSET) += ALPHA_ROUND (crtl->outgoing_args_size); \ -} + ((OFFSET) = alpha_vms_initial_elimination_offset(FROM, TO)) + /* Define a data type for recording info about an argument list during the scan of that argument list. This data type should