Backport from FSF mainline: Julian Brown Mark Mitchell gcc/ * config/arm/arm.c (arm_function_ok_for_sibcall): Only forbid sibling calls for Thumb-1. * config/arm/arm.h (USE_RETURN_INSN): Enable for Thumb-2. * config/arm/arm.md (*call_symbol, *call_value_symbol): Use for Thumb-2. (*call_insn, *call_value_insn): Don't use for Thumb-2. (sibcall, sibcall_value, *sibcall_insn, *sibcall_value_insn): Use for Thumb-2. (return): New expander. (*arm_return): New name for ARM return insn. * config/arm/thumb2.md (*thumb2_return): New insn pattern. 2010-07-26 Julian Brown Merge from Sourcery G++ 4.4: 2010-02-04 Daniel Jacobowitz === modified file 'gcc/config/arm/arm.c' --- old/gcc/config/arm/arm.c 2010-08-12 16:18:41 +0000 +++ new/gcc/config/arm/arm.c 2010-08-13 10:30:35 +0000 @@ -4886,8 +4886,8 @@ return false; /* Never tailcall something for which we have no decl, or if we - are in Thumb mode. */ - if (decl == NULL || TARGET_THUMB) + are generating code for Thumb-1. */ + if (decl == NULL || TARGET_THUMB1) return false; /* The PIC register is live on entry to VxWorks PLT entries, so we === modified file 'gcc/config/arm/arm.h' --- old/gcc/config/arm/arm.h 2010-08-12 16:18:41 +0000 +++ new/gcc/config/arm/arm.h 2010-08-13 10:30:35 +0000 @@ -1833,11 +1833,8 @@ /* Determine if the epilogue should be output as RTL. You should override this if you define FUNCTION_EXTRA_EPILOGUE. */ -/* This is disabled for Thumb-2 because it will confuse the - conditional insn counter. - Do not use a return insn if we're avoiding ldm/stm instructions. */ #define USE_RETURN_INSN(ISCOND) \ - ((TARGET_ARM && !low_irq_latency) ? use_return_insn (ISCOND, NULL) : 0) + ((TARGET_32BIT && !low_irq_latency) ? use_return_insn (ISCOND, NULL) : 0) /* Definitions for register eliminations. === modified file 'gcc/config/arm/arm.md' --- old/gcc/config/arm/arm.md 2010-08-12 16:47:21 +0000 +++ new/gcc/config/arm/arm.md 2010-08-13 10:30:35 +0000 @@ -8798,7 +8798,7 @@ (match_operand 1 "" "")) (use (match_operand 2 "" "")) (clobber (reg:SI LR_REGNUM))] - "TARGET_ARM + "TARGET_32BIT && (GET_CODE (operands[0]) == SYMBOL_REF) && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))" "* @@ -8814,7 +8814,7 @@ (match_operand:SI 2 "" ""))) (use (match_operand 3 "" "")) (clobber (reg:SI LR_REGNUM))] - "TARGET_ARM + "TARGET_32BIT && (GET_CODE (operands[1]) == SYMBOL_REF) && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))" "* @@ -8829,7 +8829,7 @@ (match_operand:SI 1 "" "")) (use (match_operand 2 "" "")) (clobber (reg:SI LR_REGNUM))] - "TARGET_THUMB + "TARGET_THUMB1 && GET_CODE (operands[0]) == SYMBOL_REF && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))" "bl\\t%a0" @@ -8843,7 +8843,7 @@ (match_operand 2 "" ""))) (use (match_operand 3 "" "")) (clobber (reg:SI LR_REGNUM))] - "TARGET_THUMB + "TARGET_THUMB1 && GET_CODE (operands[1]) == SYMBOL_REF && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))" "bl\\t%a1" @@ -8857,7 +8857,7 @@ (match_operand 1 "general_operand" "")) (return) (use (match_operand 2 "" ""))])] - "TARGET_ARM" + "TARGET_32BIT" " { if (operands[2] == NULL_RTX) @@ -8871,7 +8871,7 @@ (match_operand 2 "general_operand" ""))) (return) (use (match_operand 3 "" ""))])] - "TARGET_ARM" + "TARGET_32BIT" " { if (operands[3] == NULL_RTX) @@ -8884,7 +8884,7 @@ (match_operand 1 "" "")) (return) (use (match_operand 2 "" ""))] - "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF" + "TARGET_32BIT && GET_CODE (operands[0]) == SYMBOL_REF" "* return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\"; " @@ -8897,15 +8897,20 @@ (match_operand 2 "" ""))) (return) (use (match_operand 3 "" ""))] - "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF" + "TARGET_32BIT && GET_CODE (operands[1]) == SYMBOL_REF" "* return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\"; " [(set_attr "type" "call")] ) +(define_expand "return" + [(return)] + "TARGET_32BIT && USE_RETURN_INSN (FALSE)" + "") + ;; Often the return insn will be the same as loading from memory, so set attr -(define_insn "return" +(define_insn "*arm_return" [(return)] "TARGET_ARM && USE_RETURN_INSN (FALSE)" "* === modified file 'gcc/config/arm/thumb2.md' --- old/gcc/config/arm/thumb2.md 2010-08-12 16:47:21 +0000 +++ new/gcc/config/arm/thumb2.md 2010-08-13 10:30:35 +0000 @@ -1054,6 +1054,19 @@ (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")] +) + (define_insn_and_split "thumb2_eh_return" [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")] VUNSPEC_EH_RETURN)