This is the mail archive of the gcc-patches@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]

[Patch ARM] PR target/19599 Enable sibcalls through function pointers.


Hi,

This patch allows sibling calls through function pointers on the ARM
port. Testing currently on a qemu cross to cortex-a8 on arm-none-eabi
cross.

The one case (as Richard pointed out this morning ) not considered
with this patch is that it doesn't consider the corner case of users
trying to use -fcaller-save and -fcallee-save from the command line
but the caller-save callee-save bits of the ABI for this are quite
hard-coded in the ARM backend that one will have to rewrite quite a
few bits in the backend to get those options supported properly.

Ok to commit if no regressions ?


cheers
Ramana



2009-06-02  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
	
        PR target/19599	
	* config/arm/predicates.md (call_insn_operand): New predicate.
	* config/arm/constraints.md ("Cs"): New register constraint.
	("Ss"): New constraint for symbol references.
	* config/arm/arm.md (sibcall): Allow only memory indirects through
	symbol refs or register operands for operands[0].
	(sibcall_value): Likewise for operands[1].
	(*sibcall_insn): Allow register indirect sibcalls.
	(*sibcall_value): Allow register indirect sibcalls.
	* config/arm/arm.h (enum reg_class): New reg class ARM_CALLER_SAVE_REGS.
	(REG_CLASS_NAMES): Likewise.
	(REG_CLASS_CONTENTS): Likewise.
	* config/arm/arm.c (arm_function_ok_for_sibcall): Remove check for
	functions without decls. Handle fallout of NULL decls.
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 148103)
+++ gcc/config/arm/arm.c	(working copy)
@@ -3545,7 +3545,7 @@ arm_function_ok_for_sibcall (tree decl, 
 
   /* Never tailcall something for which we have no decl, or if we
      are in Thumb mode.  */
-  if (decl == NULL || TARGET_THUMB)
+  if (TARGET_THUMB)
     return false;
 
   /* The PIC register is live on entry to VxWorks PLT entries, so we
@@ -3555,13 +3555,15 @@ arm_function_ok_for_sibcall (tree decl, 
 
   /* Cannot tail-call to long calls, since these are out of range of
      a branch instruction.  */
-  if (arm_is_long_call_p (decl))
+  if ((decl != NULL) 
+      && arm_is_long_call_p (decl))
     return false;
 
   /* If we are interworking and the function is not declared static
      then we can't tail-call it unless we know that it exists in this
      compilation unit (since it might be a Thumb routine).  */
-  if (TARGET_INTERWORK && TREE_PUBLIC (decl) && !TREE_ASM_WRITTEN (decl))
+  if (TARGET_INTERWORK && (decl != NULL) && TREE_PUBLIC (decl) && 
+      !TREE_ASM_WRITTEN (decl))
     return false;
 
   func_type = arm_current_func_type ();
Index: gcc/config/arm/arm.h
===================================================================
--- gcc/config/arm/arm.h	(revision 148103)
+++ gcc/config/arm/arm.h	(working copy)
@@ -1133,6 +1133,7 @@ enum reg_class
   STACK_REG,
   BASE_REGS,
   HI_REGS,
+  ARM_CALLER_SAVE_REGS,
   CC_REG,
   VFPCC_REG,
   GENERAL_REGS,
@@ -1159,6 +1160,7 @@ enum reg_class
   "STACK_REG",		\
   "BASE_REGS",		\
   "HI_REGS",		\
+  "ARM_CALLER_SAVE_REGS", \
   "CC_REG",		\
   "VFPCC_REG",		\
   "GENERAL_REGS",	\
@@ -1184,6 +1186,7 @@ enum reg_class
   { 0x00002000, 0x00000000, 0x00000000, 0x00000000 }, /* STACK_REG */	\
   { 0x000020FF, 0x00000000, 0x00000000, 0x00000000 }, /* BASE_REGS */	\
   { 0x0000DF00, 0x00000000, 0x00000000, 0x00000000 }, /* HI_REGS */	\
+  { 0x0000100F, 0x00000000, 0x00000000, 0x00000000 }, /* ARM_CALLER_SAVE_REGS */ \
   { 0x01000000, 0x00000000, 0x00000000, 0x00000000 }, /* CC_REG */	\
   { 0x00000000, 0x00000000, 0x00000000, 0x80000000 }, /* VFPCC_REG */	\
   { 0x0200DFFF, 0x00000000, 0x00000000, 0x00000000 }, /* GENERAL_REGS */ \
Index: gcc/config/arm/arm.md
===================================================================
--- gcc/config/arm/arm.md	(revision 148103)
+++ gcc/config/arm/arm.md	(working copy)
@@ -8424,13 +8424,17 @@ (define_insn "*call_value_insn"
 
 ;; We may also be able to do sibcalls for Thumb, but it's much harder...
 (define_expand "sibcall"
-  [(parallel [(call (match_operand 0 "memory_operand" "")
-		    (match_operand 1 "general_operand" ""))
+  [(parallel [(call (match_operand 0 "" "")
+		    (match_operand 1 "" ""))
 	      (return)
 	      (use (match_operand 2 "" ""))])]
   "TARGET_ARM"
   "
   {
+    if (!REG_P (XEXP (operands[0], 0)) 
+       && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
+     XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
+	
     if (operands[2] == NULL_RTX)
       operands[2] = const0_rtx;
   }"
@@ -8438,39 +8442,55 @@ (define_expand "sibcall"
 
 (define_expand "sibcall_value"
   [(parallel [(set (match_operand 0 "" "")
-		   (call (match_operand 1 "memory_operand" "")
-			 (match_operand 2 "general_operand" "")))
+		   (call (match_operand 1 "" "")
+			 (match_operand 2 "" "")))
 	      (return)
 	      (use (match_operand 3 "" ""))])]
   "TARGET_ARM"
   "
   {
+    if (!REG_P (XEXP (operands[1], 0)) && 
+       (GET_CODE (XEXP (operands[1],0)) != SYMBOL_REF))
+     XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
+
     if (operands[3] == NULL_RTX)
       operands[3] = const0_rtx;
   }"
 )
 
 (define_insn "*sibcall_insn"
- [(call (mem:SI (match_operand:SI 0 "" "X"))
+ [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs,Ss"))
 	(match_operand 1 "" ""))
   (return)
   (use (match_operand 2 "" ""))]
-  "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF"
+  "TARGET_ARM"
   "*
-  return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
+  if (which_alternative == 1)
+    return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\";
+  else 
+    if (arm_arch5 || arm_arch4t)
+    return \" bx\\t%0\\t%@ indirect register sibling call\";
+    else
+     return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\";
   "
   [(set_attr "type" "call")]
 )
 
 (define_insn "*sibcall_value_insn"
- [(set (match_operand 0 "" "")
-       (call (mem:SI (match_operand:SI 1 "" "X"))
+ [(set (match_operand 0 "s_register_operand" "")
+       (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,Ss"))
 	     (match_operand 2 "" "")))
   (return)
   (use (match_operand 3 "" ""))]
-  "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF"
+  "TARGET_ARM"
   "*
-  return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
+  if (which_alternative == 1)
+   return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\";
+  else
+  if (arm_arch5 || arm_arch4t)
+   return \"bx\\t%1\";
+  else
+   return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \";
   "
   [(set_attr "type" "call")]
 )
Index: gcc/config/arm/constraints.md
===================================================================
--- gcc/config/arm/constraints.md	(revision 148103)
+++ gcc/config/arm/constraints.md	(working copy)
@@ -75,6 +75,9 @@ (define_register_constraint "b" "TARGET_
 (define_register_constraint "c" "CC_REG"
  "@internal The condition code register.")
 
+(define_register_constraint "Cs" "ARM_CALLER_SAVE_REGS"
+ "@internal The caller save registers. Useful for sibcalls.")
+
 (define_constraint "I"
  "In ARM/Thumb-2 state a constant that can be used as an immediate value in a
   Data Processing instruction.  In Thumb-1 state a constant in the range
@@ -247,9 +250,16 @@ (define_memory_constraint "Q"
  (and (match_code "mem")
       (match_test "REG_P (XEXP (op, 0))")))
 
-;; We used to have constraint letters for S and R in ARM state, but
+;; We used to have constraint letters for R in ARM state, but
 ;; all uses of these now appear to have been removed.
 
 ;; Additionally, we used to have a Q constraint in Thumb state, but
 ;; this wasn't really a valid memory constraint.  Again, all uses of
 ;; this now seem to have been removed.
+
+(define_constraint "Ss"
+ "@internal
+  In ARM state S is a symbol reference."
+ (match_code "symbol_ref")
+)
+ 
\ No newline at end of file
Index: gcc/config/arm/predicates.md
===================================================================
--- gcc/config/arm/predicates.md	(revision 148103)
+++ gcc/config/arm/predicates.md	(working copy)
@@ -517,3 +517,6 @@ (define_predicate "neon_lane_number"
   (and (match_code "const_int")
        (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 7")))
 
+(define_predicate "call_insn_operand"
+  (ior (match_code "symbol_ref")
+       (match_operand 0 "s_register_operand")))

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