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
This commit is contained in:
Olivier Hainque 2009-08-11 05:14:48 +00:00 committed by Douglas Rupp
parent 18fd562170
commit 1d3499d85c
4 changed files with 118 additions and 39 deletions

View File

@ -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>

View File

@ -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);

View File

@ -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;
}
int
alpha_pv_save_size (void)
{
alpha_sa_size ();
return alpha_procedure_type == PT_STACK ? 8 : 0;
}
int
alpha_using_fp (void)
{
alpha_sa_size ();
return vms_unwind_regno == HARD_FRAME_POINTER_REGNUM;
}
#if TARGET_ABI_OPEN_VMS
int
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 ();
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 ();
}
/* 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;
}
}
#define COMMON_OBJECT "common_object"
static tree

View File

@ -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