From d5db54a12c1fec54208876b4137ab09851fe6565 Mon Sep 17 00:00:00 2001 From: Richard Earnshaw Date: Fri, 1 Nov 2002 14:41:57 +0000 Subject: [PATCH] re PR target/7856 ([arm] invalid offset in constant pool reference) PR target/7856 * arm.c (use_return_insn): Don't use a return insn if there are saved integer regs, but LR is not one of them. From-SVN: r58716 --- gcc/ChangeLog | 6 ++++++ gcc/config/arm/arm.c | 29 +++++++++++++++++++---------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 85f6174594a..d904fc4eacc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2002-11-01 Richard Earnshaw (rearnsha@arm.com) + + PR target/7856 + * arm.c (use_return_insn): Don't use a return insn if there are + saved integer regs, but LR is not one of them. + Fri Nov 1 10:33:15 CET 2002 Jan Hubicka * expr.c (emit_move_insn): Use SCALAR_FLOAT_MODE_P diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index b06cb9bb337..5c0eea7cd9d 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -909,6 +909,7 @@ use_return_insn (iscond) { int regno; unsigned int func_type; + unsigned long saved_int_regs; /* Never use a return instruction before reload has run. */ if (!reload_completed) @@ -931,23 +932,31 @@ use_return_insn (iscond) && !frame_pointer_needed)) return 0; + saved_int_regs = arm_compute_save_reg_mask (); + /* Can't be done if interworking with Thumb, and any registers have been - stacked. Similarly, on StrongARM, conditional returns are expensive - if they aren't taken and registers have been stacked. */ - if (iscond && arm_is_strong && frame_pointer_needed) + stacked. */ + if (TARGET_INTERWORK && saved_int_regs != 0) return 0; - - if ((iscond && arm_is_strong) - || TARGET_INTERWORK) + + /* On StrongARM, conditional returns are expensive if they aren't + taken and multiple registers have been stacked. */ + if (iscond && arm_is_strong) { - for (regno = 0; regno <= LAST_ARM_REGNUM; regno++) - if (regs_ever_live[regno] && !call_used_regs[regno]) - return 0; + /* Conditional return when just the LR is stored is a simple + conditional-load instruction, that's not expensive. */ + if (saved_int_regs != 0 && saved_int_regs != (1 << LR_REGNUM)) + return 0; if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM]) return 0; } - + + /* If there are saved registers but the LR isn't saved, then we need + two instructions for the return. */ + if (saved_int_regs && !(saved_int_regs & (1 << LR_REGNUM))) + return 0; + /* Can't be done if any of the FPU regs are pushed, since this also requires an insn. */ if (TARGET_HARD_FLOAT) -- 2.30.2