This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: ARM/THUMB long calls stubs
Hi Sami, Hi Richard,
Would it be hard to fix this? So that gcc would take __attribute__
((section())) in account when determining if functions are in different
sections or not. Feels bad as all functions are called with the long call..
I think that this is a real bug in gcc.
The problem appears to be that the short-call attribute is being set for
any function that has already been compiled in a compilation unit,
regardless of whether that function has a section attribute or not. In
effect this is saying that the compiler thinks that any function it has
already compiled must be within a short-call range of any function that
it is about to compile.
The attached patch removes this assumption and tidies up some of the
comments in the code associated with the arm_is_longcall_p(). I have
tested it with an arm-elf build and found no regressions, so unless
Richard has any objections I plan to check it in later this week.
Cheers
Nick
gcc/ChangeLog
2004-08-09 Nick Clifton <nickc@redhat.com>
* config/arm/arm.c (arm_is_longcall_p): When -mlong-call is in
effect allow long calling when either the current or target
function has the section attribute or -ffunction-sections is in
effect.
* config/arm/arm.h (ARM_DECLARE_FUNCTION_SIZE): Do not set the
short-call attribute when the function has the section attribute
and -mlong-call is in effect.
Index: gcc/config/arm/arm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
retrieving revision 1.383
diff -c -3 -p -r1.383 arm.c
*** gcc/config/arm/arm.c 6 Aug 2004 02:03:22 -0000 1.383
--- gcc/config/arm/arm.c 9 Aug 2004 08:40:30 -0000
*************** current_file_function_operand (rtx sym_r
*** 2651,2657 ****
return 1;
/* The current function is always defined within the current compilation
! unit. if it s a weak definition however, then this may not be the real
definition of the function, and so we have to say no. */
if (sym_ref == XEXP (DECL_RTL (current_function_decl), 0)
&& !DECL_WEAK (current_function_decl))
--- 2651,2657 ----
return 1;
/* The current function is always defined within the current compilation
! unit. If it s a weak definition however, then this may not be the real
definition of the function, and so we have to say no. */
if (sym_ref == XEXP (DECL_RTL (current_function_decl), 0)
&& !DECL_WEAK (current_function_decl))
*************** current_file_function_operand (rtx sym_r
*** 2667,2682 ****
a. has an __attribute__((long call))
or b. is within the scope of a #pragma long_calls
or c. the -mlong-calls command line switch has been specified
However we do not generate a long call if the function:
d. has an __attribute__ ((short_call))
or e. is inside the scope of a #pragma no_long_calls
! or f. has an __attribute__ ((section))
! or g. is defined within the current compilation unit.
This function will be called by C fragments contained in the machine
! description file. CALL_REF and CALL_COOKIE correspond to the matched
rtl operands. CALL_SYMBOL is used to distinguish between
two different callers of the function. It is set to 1 in the
"call_symbol" and "call_symbol_value" patterns and to 0 in the "call"
--- 2667,2685 ----
a. has an __attribute__((long call))
or b. is within the scope of a #pragma long_calls
or c. the -mlong-calls command line switch has been specified
+ . and either:
+ 1. -ffunction-sections is in effect
+ or 2. the current function has __attribute__ ((section))
+ or 3. the target function has __attribute__ ((section))
However we do not generate a long call if the function:
d. has an __attribute__ ((short_call))
or e. is inside the scope of a #pragma no_long_calls
! or f. is defined within the current compilation unit.
This function will be called by C fragments contained in the machine
! description file. SYM_REF and CALL_COOKIE correspond to the matched
rtl operands. CALL_SYMBOL is used to distinguish between
two different callers of the function. It is set to 1 in the
"call_symbol" and "call_symbol_value" patterns and to 0 in the "call"
*************** arm_is_longcall_p (rtx sym_ref, int call
*** 2699,2707 ****
if (call_cookie & CALL_SHORT)
return 0;
! if (TARGET_LONG_CALLS && flag_function_sections)
! return 1;
!
if (current_file_function_operand (sym_ref))
return 0;
--- 2702,2716 ----
if (call_cookie & CALL_SHORT)
return 0;
! if (TARGET_LONG_CALLS)
! {
! if (flag_function_sections
! || DECL_SECTION_NAME (current_function_decl))
! /* c.3 is handled by the defintion of the
! ARM_DECLARE_FUNCTION_SIZE macro. */
! return 1;
! }
!
if (current_file_function_operand (sym_ref))
return 0;
Index: gcc/config/arm/arm.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.h,v
retrieving revision 1.245
diff -c -3 -p -r1.245 arm.h
*** gcc/config/arm/arm.h 14 Jul 2004 17:51:18 -0000 1.245
--- gcc/config/arm/arm.h 9 Aug 2004 08:40:33 -0000
*************** typedef struct
*** 2048,2055 ****
#define ASM_OUTPUT_LABELREF(FILE, NAME) \
arm_asm_output_labelref (FILE, NAME)
#define ARM_DECLARE_FUNCTION_SIZE(STREAM, NAME, DECL) \
! arm_encode_call_attribute (DECL, SHORT_CALL_FLAG_CHAR)
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
--- 2048,2061 ----
#define ASM_OUTPUT_LABELREF(FILE, NAME) \
arm_asm_output_labelref (FILE, NAME)
+ /* Set the short-call flag for any function compiled in the current
+ compilation unit. We skip this for functions with the section
+ attirubte when long-calls are in effect as this tells the compiler
+ that the section might be placed a long way from the caller.
+ See arm_is_longcall_p() for more information. */
#define ARM_DECLARE_FUNCTION_SIZE(STREAM, NAME, DECL) \
! if (!TARGET_LONG_CALLS || ! DECL_SECTION_NAME (DECL)) \
! arm_encode_call_attribute (DECL, SHORT_CALL_FLAG_CHAR)
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.