mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-25 12:41:01 +08:00
rs6000-protos.h (rs6000_initial_elimination_offset): Add.
2003-11-12 Janis Johnson <janis187@us.ibm.com> * rs6000-protos.h (rs6000_initial_elimination_offset): Add. (rs6000_stack_info): Remove. (debug_stack_info): Remove. (rs6000_emit_eh_reg_restore): Add * rs6000.c (rs6000_stack_t): Move from rs6000.h, change data type of vars_size and total_size to HOST_WIDE_INT. (emit_frame_save): Change parameter size to HOST_WIDE_INT. (rs6000_stack_info): Make static; change data size to HOST_WIDE_INT. (debug_stack_info): Make static; change output format of HOST_WIDE_INT values. (rs6000_emit_eh_reg_restore): New, with code formerly in rs6000.md. (rs6000_initial_elimination_offset): New, with code formerly in INITIAL_ELIMINATION_OFFSET. * rs6000.h (rs6000_stack_t): Remove. (INITIAL_ELIMINATION_OFFSET): Replace code with call to function rs6000_initial_elimination_offset. * rs6000.md (UNSPECV_EH_RR split): Replace code with call to rs6000_emit_eh_reg_restore. From-SVN: r73517
This commit is contained in:
parent
8f120836ef
commit
d1d0c603c4
@ -1,3 +1,23 @@
|
||||
2003-11-12 Janis Johnson <janis187@us.ibm.com>
|
||||
|
||||
* rs6000-protos.h (rs6000_initial_elimination_offset): Add.
|
||||
(rs6000_stack_info): Remove. (debug_stack_info): Remove.
|
||||
(rs6000_emit_eh_reg_restore): Add
|
||||
* rs6000.c (rs6000_stack_t): Move from rs6000.h, change data type
|
||||
of vars_size and total_size to HOST_WIDE_INT.
|
||||
(emit_frame_save): Change parameter size to HOST_WIDE_INT.
|
||||
(rs6000_stack_info): Make static; change data size to HOST_WIDE_INT.
|
||||
(debug_stack_info): Make static; change output format of HOST_WIDE_INT
|
||||
values.
|
||||
(rs6000_emit_eh_reg_restore): New, with code formerly in rs6000.md.
|
||||
(rs6000_initial_elimination_offset): New, with code formerly in
|
||||
INITIAL_ELIMINATION_OFFSET.
|
||||
* rs6000.h (rs6000_stack_t): Remove.
|
||||
(INITIAL_ELIMINATION_OFFSET): Replace code with call to function
|
||||
rs6000_initial_elimination_offset.
|
||||
* rs6000.md (UNSPECV_EH_RR split): Replace code with call to
|
||||
rs6000_emit_eh_reg_restore.
|
||||
|
||||
2003-11-12 Mike Stump <mrs@apple.com>
|
||||
|
||||
* c-typeck.c (c_convert_parm_for_inlining): Add argnum, which
|
||||
|
@ -134,6 +134,7 @@ extern int rs6000_legitimate_address (enum machine_mode, rtx, int);
|
||||
extern bool rs6000_mode_dependent_address (rtx);
|
||||
extern rtx rs6000_return_addr (int, rtx);
|
||||
extern void rs6000_output_symbol_ref (FILE*, rtx);
|
||||
extern HOST_WIDE_INT rs6000_initial_elimination_offset (int, int);
|
||||
|
||||
extern rtx rs6000_machopic_legitimize_pic_address (rtx orig,
|
||||
enum machine_mode mode, rtx reg);
|
||||
@ -168,7 +169,6 @@ extern void rs6000_override_options (const char *);
|
||||
extern int direct_return (void);
|
||||
extern int first_reg_to_save (void);
|
||||
extern int first_fp_reg_to_save (void);
|
||||
extern rs6000_stack_t *rs6000_stack_info (void);
|
||||
extern void output_ascii (FILE *, const char *, int);
|
||||
extern void rs6000_gen_section_name (char **, const char *, const char *);
|
||||
extern void output_function_profiler (FILE *, int);
|
||||
@ -187,7 +187,7 @@ extern void rs6000_emit_prologue (void);
|
||||
extern void rs6000_emit_load_toc_table (int);
|
||||
extern void rs6000_aix_emit_builtin_unwind_init (void);
|
||||
extern void rs6000_emit_epilogue (int);
|
||||
extern void debug_stack_info (rs6000_stack_t *);
|
||||
extern void rs6000_emit_eh_reg_restore (rtx, rtx);
|
||||
extern const char * output_isel (rtx *);
|
||||
extern int vrsave_operation (rtx, enum machine_mode);
|
||||
extern int rs6000_register_move_cost (enum machine_mode,
|
||||
|
@ -70,6 +70,49 @@
|
||||
#define min(A,B) ((A) < (B) ? (A) : (B))
|
||||
#define max(A,B) ((A) > (B) ? (A) : (B))
|
||||
|
||||
/* Structure used to define the rs6000 stack */
|
||||
typedef struct rs6000_stack {
|
||||
int first_gp_reg_save; /* first callee saved GP register used */
|
||||
int first_fp_reg_save; /* first callee saved FP register used */
|
||||
int first_altivec_reg_save; /* first callee saved AltiVec register used */
|
||||
int lr_save_p; /* true if the link reg needs to be saved */
|
||||
int cr_save_p; /* true if the CR reg needs to be saved */
|
||||
unsigned int vrsave_mask; /* mask of vec registers to save */
|
||||
int toc_save_p; /* true if the TOC needs to be saved */
|
||||
int push_p; /* true if we need to allocate stack space */
|
||||
int calls_p; /* true if the function makes any calls */
|
||||
enum rs6000_abi abi; /* which ABI to use */
|
||||
int gp_save_offset; /* offset to save GP regs from initial SP */
|
||||
int fp_save_offset; /* offset to save FP regs from initial SP */
|
||||
int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
|
||||
int lr_save_offset; /* offset to save LR from initial SP */
|
||||
int cr_save_offset; /* offset to save CR from initial SP */
|
||||
int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
|
||||
int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
|
||||
int toc_save_offset; /* offset to save the TOC pointer */
|
||||
int varargs_save_offset; /* offset to save the varargs registers */
|
||||
int ehrd_offset; /* offset to EH return data */
|
||||
int reg_size; /* register size (4 or 8) */
|
||||
int varargs_size; /* size to hold V.4 args passed in regs */
|
||||
HOST_WIDE_INT vars_size; /* variable save area size */
|
||||
int parm_size; /* outgoing parameter size */
|
||||
int save_size; /* save area size */
|
||||
int fixed_size; /* fixed size of stack frame */
|
||||
int gp_size; /* size of saved GP registers */
|
||||
int fp_size; /* size of saved FP registers */
|
||||
int altivec_size; /* size of saved AltiVec registers */
|
||||
int cr_size; /* size to hold CR if not in save_size */
|
||||
int lr_size; /* size to hold LR if not in save_size */
|
||||
int vrsave_size; /* size to hold VRSAVE if not in save_size */
|
||||
int altivec_padding_size; /* size of altivec alignment padding if
|
||||
not in save_size */
|
||||
int spe_gp_size; /* size of 64-bit GPR save size for SPE */
|
||||
int spe_padding_size;
|
||||
int toc_size; /* size to hold TOC if not in save_size */
|
||||
HOST_WIDE_INT total_size; /* total bytes allocated for stack */
|
||||
int spe_64bit_regs_used;
|
||||
} rs6000_stack_t;
|
||||
|
||||
/* Target cpu type */
|
||||
|
||||
enum processor_type rs6000_cpu;
|
||||
@ -222,7 +265,7 @@ static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
|
||||
static rtx spe_synthesize_frame_save (rtx);
|
||||
static bool spe_func_has_64bit_regs_p (void);
|
||||
static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
|
||||
int, int);
|
||||
int, HOST_WIDE_INT);
|
||||
static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
|
||||
static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int);
|
||||
static unsigned rs6000_hash_constant (rtx);
|
||||
@ -317,6 +360,8 @@ static rtx spe_expand_builtin (tree, rtx, bool *);
|
||||
static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
|
||||
static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
|
||||
static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
|
||||
static rs6000_stack_t *rs6000_stack_info (void);
|
||||
static void debug_stack_info (rs6000_stack_t *);
|
||||
|
||||
static rtx altivec_expand_builtin (tree, rtx, bool *);
|
||||
static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
|
||||
@ -10269,14 +10314,14 @@ is_altivec_return_reg (rtx reg, void *xyes)
|
||||
#define ABI_STACK_BOUNDARY STACK_BOUNDARY
|
||||
#endif
|
||||
|
||||
rs6000_stack_t *
|
||||
static rs6000_stack_t *
|
||||
rs6000_stack_info (void)
|
||||
{
|
||||
static rs6000_stack_t info, zero_info;
|
||||
rs6000_stack_t *info_ptr = &info;
|
||||
int reg_size = TARGET_POWERPC64 ? 8 : 4;
|
||||
int ehrd_size;
|
||||
int total_raw_size;
|
||||
HOST_WIDE_INT total_raw_size;
|
||||
|
||||
/* Zero all fields portably. */
|
||||
info = zero_info;
|
||||
@ -10608,7 +10653,7 @@ spe_func_has_64bit_regs_p (void)
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
debug_stack_info (rs6000_stack_t *info)
|
||||
{
|
||||
const char *abi_string;
|
||||
@ -10697,13 +10742,15 @@ debug_stack_info (rs6000_stack_t *info)
|
||||
fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
|
||||
|
||||
if (info->total_size)
|
||||
fprintf (stderr, "\ttotal_size = %5d\n", info->total_size);
|
||||
fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
|
||||
info->total_size);
|
||||
|
||||
if (info->varargs_size)
|
||||
fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size);
|
||||
|
||||
if (info->vars_size)
|
||||
fprintf (stderr, "\tvars_size = %5d\n", info->vars_size);
|
||||
fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
|
||||
info->vars_size);
|
||||
|
||||
if (info->parm_size)
|
||||
fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
|
||||
@ -10976,6 +11023,42 @@ rs6000_emit_load_toc_table (int fromprolog)
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Emit instructions to restore the link register after determining where
|
||||
its value has been stored. */
|
||||
|
||||
void
|
||||
rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
|
||||
{
|
||||
rs6000_stack_t *info = rs6000_stack_info ();
|
||||
rtx operands[2];
|
||||
|
||||
operands[0] = source;
|
||||
operands[1] = scratch;
|
||||
|
||||
if (info->lr_save_p)
|
||||
{
|
||||
rtx frame_rtx = stack_pointer_rtx;
|
||||
HOST_WIDE_INT sp_offset = 0;
|
||||
rtx tmp;
|
||||
|
||||
if (frame_pointer_needed
|
||||
|| current_function_calls_alloca
|
||||
|| info->total_size > 32767)
|
||||
{
|
||||
emit_move_insn (operands[1], gen_rtx_MEM (Pmode, frame_rtx));
|
||||
frame_rtx = operands[1];
|
||||
}
|
||||
else if (info->push_p)
|
||||
sp_offset = info->total_size;
|
||||
|
||||
tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
|
||||
tmp = gen_rtx_MEM (Pmode, tmp);
|
||||
emit_move_insn (tmp, operands[0]);
|
||||
}
|
||||
else
|
||||
emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
|
||||
}
|
||||
|
||||
int
|
||||
get_TOC_alias_set (void)
|
||||
{
|
||||
@ -11374,7 +11457,7 @@ generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
|
||||
|
||||
static void
|
||||
emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
|
||||
unsigned int regno, int offset, int total_size)
|
||||
unsigned int regno, int offset, HOST_WIDE_INT total_size)
|
||||
{
|
||||
rtx reg, offset_rtx, insn, mem, addr, int_rtx;
|
||||
rtx replacea, replaceb;
|
||||
@ -15575,6 +15658,28 @@ rs6000_libcall_value (enum machine_mode mode)
|
||||
return gen_rtx_REG (mode, regno);
|
||||
}
|
||||
|
||||
/* Define the offset between two registers, FROM to be eliminated and its
|
||||
replacement TO, at the start of a routine. */
|
||||
HOST_WIDE_INT
|
||||
rs6000_initial_elimination_offset (int from, int to)
|
||||
{
|
||||
rs6000_stack_t *info = rs6000_stack_info ();
|
||||
HOST_WIDE_INT offset;
|
||||
|
||||
if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
|
||||
offset = info->push_p ? 0 : -info->total_size;
|
||||
else if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
|
||||
offset = info->total_size;
|
||||
else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
|
||||
offset = info->push_p ? info->total_size : 0;
|
||||
else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
|
||||
offset = 0;
|
||||
else
|
||||
abort ();
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* Return true if TYPE is of type __ev64_opaque__. */
|
||||
|
||||
static bool
|
||||
|
@ -1491,49 +1491,6 @@ enum rs6000_abi {
|
||||
|
||||
extern enum rs6000_abi rs6000_current_abi; /* available for use by subtarget */
|
||||
|
||||
/* Structure used to define the rs6000 stack */
|
||||
typedef struct rs6000_stack {
|
||||
int first_gp_reg_save; /* first callee saved GP register used */
|
||||
int first_fp_reg_save; /* first callee saved FP register used */
|
||||
int first_altivec_reg_save; /* first callee saved AltiVec register used */
|
||||
int lr_save_p; /* true if the link reg needs to be saved */
|
||||
int cr_save_p; /* true if the CR reg needs to be saved */
|
||||
unsigned int vrsave_mask; /* mask of vec registers to save */
|
||||
int toc_save_p; /* true if the TOC needs to be saved */
|
||||
int push_p; /* true if we need to allocate stack space */
|
||||
int calls_p; /* true if the function makes any calls */
|
||||
enum rs6000_abi abi; /* which ABI to use */
|
||||
int gp_save_offset; /* offset to save GP regs from initial SP */
|
||||
int fp_save_offset; /* offset to save FP regs from initial SP */
|
||||
int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
|
||||
int lr_save_offset; /* offset to save LR from initial SP */
|
||||
int cr_save_offset; /* offset to save CR from initial SP */
|
||||
int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
|
||||
int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
|
||||
int toc_save_offset; /* offset to save the TOC pointer */
|
||||
int varargs_save_offset; /* offset to save the varargs registers */
|
||||
int ehrd_offset; /* offset to EH return data */
|
||||
int reg_size; /* register size (4 or 8) */
|
||||
int varargs_size; /* size to hold V.4 args passed in regs */
|
||||
int vars_size; /* variable save area size */
|
||||
int parm_size; /* outgoing parameter size */
|
||||
int save_size; /* save area size */
|
||||
int fixed_size; /* fixed size of stack frame */
|
||||
int gp_size; /* size of saved GP registers */
|
||||
int fp_size; /* size of saved FP registers */
|
||||
int altivec_size; /* size of saved AltiVec registers */
|
||||
int cr_size; /* size to hold CR if not in save_size */
|
||||
int lr_size; /* size to hold LR if not in save_size */
|
||||
int vrsave_size; /* size to hold VRSAVE if not in save_size */
|
||||
int altivec_padding_size; /* size of altivec alignment padding if
|
||||
not in save_size */
|
||||
int spe_gp_size; /* size of 64-bit GPR save size for SPE */
|
||||
int spe_padding_size;
|
||||
int toc_size; /* size to hold TOC if not in save_size */
|
||||
int total_size; /* total bytes allocated for stack */
|
||||
int spe_64bit_regs_used;
|
||||
} rs6000_stack_t;
|
||||
|
||||
/* Define this if pushing a word on the stack
|
||||
makes the stack pointer a smaller address. */
|
||||
#define STACK_GROWS_DOWNWARD
|
||||
@ -1984,21 +1941,8 @@ typedef struct rs6000_args
|
||||
|
||||
/* Define the offset between two registers, one to be eliminated, and the other
|
||||
its replacement, at the start of a routine. */
|
||||
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
|
||||
{ \
|
||||
rs6000_stack_t *info = rs6000_stack_info (); \
|
||||
\
|
||||
if ((FROM) == FRAME_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
|
||||
(OFFSET) = (info->push_p) ? 0 : - info->total_size; \
|
||||
else if ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM) \
|
||||
(OFFSET) = info->total_size; \
|
||||
else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \
|
||||
(OFFSET) = (info->push_p) ? info->total_size : 0; \
|
||||
else if ((FROM) == RS6000_PIC_OFFSET_TABLE_REGNUM) \
|
||||
(OFFSET) = 0; \
|
||||
else \
|
||||
abort (); \
|
||||
}
|
||||
#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
|
||||
((OFFSET) = rs6000_initial_elimination_offset(FROM, TO))
|
||||
|
||||
/* Addressing modes, and classification of registers for them. */
|
||||
|
||||
|
@ -14684,30 +14684,7 @@
|
||||
[(const_int 0)]
|
||||
"
|
||||
{
|
||||
rs6000_stack_t *info = rs6000_stack_info ();
|
||||
|
||||
if (info->lr_save_p)
|
||||
{
|
||||
rtx frame_rtx = stack_pointer_rtx;
|
||||
int sp_offset = 0;
|
||||
rtx tmp;
|
||||
|
||||
if (frame_pointer_needed
|
||||
|| current_function_calls_alloca
|
||||
|| info->total_size > 32767)
|
||||
{
|
||||
emit_move_insn (operands[1], gen_rtx_MEM (Pmode, frame_rtx));
|
||||
frame_rtx = operands[1];
|
||||
}
|
||||
else if (info->push_p)
|
||||
sp_offset = info->total_size;
|
||||
|
||||
tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
|
||||
tmp = gen_rtx_MEM (Pmode, tmp);
|
||||
emit_move_insn (tmp, operands[0]);
|
||||
}
|
||||
else
|
||||
emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
|
||||
rs6000_emit_eh_reg_restore (operands[0], operands[1]);
|
||||
DONE;
|
||||
}")
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user