diff options
author | Olivier Hainque <hainque@adacore.com> | 2009-08-11 05:14:48 +0000 |
---|---|---|
committer | Douglas Rupp <rupp@gcc.gnu.org> | 2009-08-11 05:14:48 +0000 |
commit | 1d3499d85c4948d5c5f63353f883e3e9f03ac470 (patch) | |
tree | 726a4e25c2f63f6e9ee47f0a4f11896fc99b25fc /gcc | |
parent | 18fd56217002bffa01650080d60271b4d0d3ef27 (diff) | |
download | gcc-1d3499d85c4948d5c5f63353f883e3e9f03ac470.zip gcc-1d3499d85c4948d5c5f63353f883e3e9f03ac470.tar.gz gcc-1d3499d85c4948d5c5f63353f883e3e9f03ac470.tar.bz2 |
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 <rupp@gnat.com>
From-SVN: r150646
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/config/alpha/alpha-protos.h | 6 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.c | 99 | ||||
-rw-r--r-- | gcc/config/alpha/vms.h | 21 |
4 files changed, 112 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 17d7f63..d15941a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2009-08-10 Olivier Hainque <hainqueu@adacore.com> + Douglas B Rupp <rupp@gnat.com> + + * 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 <botcazou@adacore.com> Douglas B Rupp <rupp@gnat.com> diff --git a/gcc/config/alpha/alpha-protos.h b/gcc/config/alpha/alpha-protos.h index 39091b7..43665d3 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 84c2b7c..a1ec736 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 fa7e3c2..d8d513e 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 |