This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]