aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r--gcc/config/rs6000/rs6000.c24
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