diff options
author | obrien <obrien@FreeBSD.org> | 2002-12-04 15:42:16 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2002-12-04 15:42:16 +0000 |
commit | 7a1080fa5c329ea8a9505e51ce151719955bcfa2 (patch) | |
tree | 78b77287e56e2a87be73638176124be85a8fc6c7 /contrib/gcc/config/arm | |
parent | ef3bb1318428b8cfb1c8287f61b9b1f23f9bf0b5 (diff) | |
download | FreeBSD-src-7a1080fa5c329ea8a9505e51ce151719955bcfa2.zip FreeBSD-src-7a1080fa5c329ea8a9505e51ce151719955bcfa2.tar.gz |
Gcc 3.2.1 release virgin vendor import. (19-Nov-2002)
Diffstat (limited to 'contrib/gcc/config/arm')
-rw-r--r-- | contrib/gcc/config/arm/arm.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/contrib/gcc/config/arm/arm.c b/contrib/gcc/config/arm/arm.c index f07a281..8c696c6 100644 --- a/contrib/gcc/config/arm/arm.c +++ b/contrib/gcc/config/arm/arm.c @@ -890,6 +890,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) @@ -912,23 +913,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) |