Add a new parameter to the function output_return_instruction to handle simple cases of return when no epilogue needs to be printed out.
ChangeLog: gcc 2012-05-31 Ian Bolton <ian.bol...@arm.com> Sameera Deshpande <sameera.deshpa...@arm.com> Greta Yorsh <greta.yo...@arm.com> * config/arm/arm-protos.h (output_return_instruction): New parameter. * config/arm/arm.c (output_return_instruction): New parameter. * config/arm/arm.md (arm_simple_return): New pattern. (arm_return, cond_return, cond_return_inverted): Add new arguments. * config/arm/thumb2.md (thumb2_return): Update condition and code.
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h index f61feef..01cd794 100644 --- a/gcc/config/arm/arm-protos.h +++ b/gcc/config/arm/arm-protos.h @@ -148,7 +148,7 @@ extern int arm_address_offset_is_imm (rtx); extern const char *output_add_immediate (rtx *); extern const char *arithmetic_instr (rtx, int); extern void output_ascii_pseudo_op (FILE *, const unsigned char *, int); -extern const char *output_return_instruction (rtx, int, int); +extern const char *output_return_instruction (rtx, int, int, int); extern void arm_poke_function_name (FILE *, const char *); extern void arm_final_prescan_insn (rtx); extern int arm_debugger_arg_offset (int, rtx); diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index c8642e2..e7a74e0 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -15592,9 +15592,11 @@ arm_get_vfp_saved_size (void) /* Generate a function exit sequence. If REALLY_RETURN is false, then do - everything bar the final return instruction. */ + everything bar the final return instruction. If simple_return is true, + then do not output epilogue, because it has already been emitted in RTL. */ const char * -output_return_instruction (rtx operand, int really_return, int reverse) +output_return_instruction (rtx operand, int really_return, int reverse, + int simple_return) { char conditional[10]; char instr[100]; @@ -15637,7 +15639,7 @@ output_return_instruction (rtx operand, int really_return, int reverse) offsets = arm_get_frame_offsets (); live_regs_mask = offsets->saved_regs_mask; - if (live_regs_mask) + if (!simple_return && live_regs_mask) { const char * return_reg; @@ -15765,7 +15767,7 @@ output_return_instruction (rtx operand, int really_return, int reverse) { /* The return has already been handled by loading the LR into the PC. */ - really_return = 0; + return ""; } } diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index d1c1894..867dcbe 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -8597,7 +8597,7 @@ arm_ccfsm_state += 2; return \"\"; } - return output_return_instruction (const_true_rtx, TRUE, FALSE); + return output_return_instruction (const_true_rtx, TRUE, FALSE, FALSE); }" [(set_attr "type" "load1") (set_attr "length" "12") @@ -8618,7 +8618,7 @@ arm_ccfsm_state += 2; return \"\"; } - return output_return_instruction (operands[0], TRUE, FALSE); + return output_return_instruction (operands[0], TRUE, FALSE, FALSE); }" [(set_attr "conds" "use") (set_attr "length" "12") @@ -8639,13 +8639,30 @@ arm_ccfsm_state += 2; return \"\"; } - return output_return_instruction (operands[0], TRUE, TRUE); + return output_return_instruction (operands[0], TRUE, TRUE, FALSE); }" [(set_attr "conds" "use") (set_attr "length" "12") (set_attr "type" "load1")] ) +(define_insn "*arm_simple_return" + [(simple_return)] + "TARGET_ARM" + "* + { + if (arm_ccfsm_state == 2) + { + arm_ccfsm_state += 2; + return \"\"; + } + return output_return_instruction (const_true_rtx, TRUE, FALSE, TRUE); + }" + [(set_attr "type" "branch") + (set_attr "length" "4") + (set_attr "predicable" "yes")] +) + ;; Generate a sequence of instructions to determine if the processor is ;; in 26-bit or 32-bit mode, and return the appropriate return address ;; mask. diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md index 39a2138..b7a8423 100644 --- a/gcc/config/arm/thumb2.md +++ b/gcc/config/arm/thumb2.md @@ -635,17 +635,12 @@ (set_attr "length" "20")] ) -;; Note: this is not predicable, to avoid issues with linker-generated -;; interworking stubs. (define_insn "*thumb2_return" - [(return)] - "TARGET_THUMB2 && USE_RETURN_INSN (FALSE)" - "* - { - return output_return_instruction (const_true_rtx, TRUE, FALSE); - }" - [(set_attr "type" "load1") - (set_attr "length" "12")] + [(simple_return)] + "TARGET_THUMB2" + "* return output_return_instruction (const_true_rtx, TRUE, FALSE, TRUE);" + [(set_attr "type" "branch") + (set_attr "length" "4")] ) (define_insn_and_split "thumb2_eh_return"