diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 31 |
2 files changed, 30 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dd923ac..24513c8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2005-05-13 Josh Conner <jconner@apple.com> + + * config/arm/arm.c (arm_size_return_regs): New. + (thumb_unexpanded_epilogue): replace in-line calculation + of return registers with call to arm_size_return_regs. + (use_return_insn): Include test of which registers are + being used to hold return values, to accommodate + vector return values. + 2005-05-11 Aldy Hernandez <aldyh@redhat.com> * config/rs6000/sysv4.opt (mlittle): Handle. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 4129a99..1c0f60f 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -73,6 +73,7 @@ static int thumb_far_jump_used_p (void); static bool thumb_force_lr_save (void); static int const_ok_for_op (HOST_WIDE_INT, enum rtx_code); static rtx emit_sfm (int, int); +static int arm_size_return_regs (void); #ifndef AOF_ASSEMBLER static bool arm_assemble_integer (rtx, unsigned int, int); #endif @@ -1465,9 +1466,11 @@ use_return_insn (int iscond, rtx sibling) if (!call_used_regs[3]) return 0; - /* ... that it isn't being used for a return value (always true - until we implement return-in-regs), or for a tail-call - argument ... */ + /* ... that it isn't being used for a return value ... */ + if (arm_size_return_regs () >= (4 * UNITS_PER_WORD)) + return 0; + + /* ... or for a tail-call argument ... */ if (sibling) { gcc_assert (GET_CODE (sibling) == CALL_INSN); @@ -9851,6 +9854,20 @@ emit_multi_reg_push (unsigned long mask) return par; } +/* Calculate the size of the return value that is passed in registers. */ +static int +arm_size_return_regs (void) +{ + enum machine_mode mode; + + if (current_function_return_rtx != 0) + mode = GET_MODE (current_function_return_rtx); + else + mode = DECL_MODE (DECL_RESULT (current_function_decl)); + + return GET_MODE_SIZE (mode); +} + static rtx emit_sfm (int base_reg, int count) { @@ -12920,13 +12937,7 @@ thumb_unexpanded_epilogue (void) This is more reliable that examining regs_ever_live[] because that will be set if the register is ever used in the function, not just if the register is used to hold a return value. */ - - if (current_function_return_rtx != 0) - mode = GET_MODE (current_function_return_rtx); - else - mode = DECL_MODE (DECL_RESULT (current_function_decl)); - - size = GET_MODE_SIZE (mode); + size = arm_size_return_regs (); /* The prolog may have pushed some high registers to use as work registers. e.g. the testsuite file: |