diff options
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 95f8ab5..cb64d28 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1088,6 +1088,7 @@ static const enum reg_class *rs6000_ira_cover_classes (void); const int INSN_NOT_AVAILABLE = -1; static enum machine_mode rs6000_eh_return_filter_mode (void); +static bool rs6000_can_eliminate (const int, const int); /* Hash table stuff for keeping track of TOC entries. */ @@ -1453,6 +1454,9 @@ static const struct attribute_spec rs6000_attribute_table[] = #undef TARGET_LEGITIMATE_ADDRESS_P #define TARGET_LEGITIMATE_ADDRESS_P rs6000_legitimate_address_p +#undef TARGET_CAN_ELIMINATE +#define TARGET_CAN_ELIMINATE rs6000_can_eliminate + struct gcc_target targetm = TARGET_INITIALIZER; /* Return number of consecutive hard regs needed starting at reg REGNO @@ -25011,6 +25015,26 @@ rs6000_libcall_value (enum machine_mode mode) return gen_rtx_REG (mode, regno); } + +/* Given FROM and TO register numbers, say whether this elimination is allowed. + Frame pointer elimination is automatically handled. + + For the RS/6000, if frame pointer elimination is being done, we would like + to convert ap into fp, not sp. + + We need r30 if -mminimal-toc was specified, and there are constant pool + references. */ + +bool +rs6000_can_eliminate (const int from, const int to) +{ + return (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM + ? ! frame_pointer_needed + : from == RS6000_PIC_OFFSET_TABLE_REGNUM + ? ! TARGET_MINIMAL_TOC || TARGET_NO_TOC || get_pool_size () == 0 + : true); +} + /* Define the offset between two registers, FROM to be eliminated and its replacement TO, at the start of a routine. */ HOST_WIDE_INT |