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]

Re: [PATCH] 2nd try: Add sseregparm function attribute for x86


On Thu, Jun 09, 2005 at 09:17:58PM +0200, Richard Guenther wrote:
> Using the above testcase and compiling with -O2 -msse I get ...

There are some hacks to remove from function_arg{,_advance}.

I had assumed they were your changes, actually; I guess we'll
have to figure out where they came from and what they're for...

Here's the patch I used.


r~



Index: i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.826
diff -u -p -r1.826 i386.c
--- i386.c	8 Jun 2005 05:05:18 -0000	1.826
+++ i386.c	9 Jun 2005 19:19:04 -0000
@@ -892,6 +892,7 @@ const struct attribute_spec ix86_attribu
 static bool ix86_function_ok_for_sibcall (tree, tree);
 static tree ix86_handle_cdecl_attribute (tree *, tree, tree, int, bool *);
 static tree ix86_handle_regparm_attribute (tree *, tree, tree, int, bool *);
+static tree ix86_handle_sseregparm_attribute (tree *, tree, tree, int, bool *);
 static int ix86_value_regno (enum machine_mode, tree);
 static bool contains_128bit_aligned_vector_p (tree);
 static rtx ix86_struct_value_rtx (tree, int);
@@ -1659,6 +1660,9 @@ const struct attribute_spec ix86_attribu
   /* Regparm attribute specifies how many integer arguments are to be
      passed in registers.  */
   { "regparm",   1, 1, false, true,  true,  ix86_handle_regparm_attribute },
+  /* Sseregparm attribute says we are using x86_64 calling conventions
+     for FP arguments.  */
+  { "sseregparm", 0, 0, false, true, true, ix86_handle_sseregparm_attribute },
 #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
   { "dllimport", 0, 0, false, false, false, handle_dll_attribute },
   { "dllexport", 0, 0, false, false, false, handle_dll_attribute },
@@ -1824,6 +1828,25 @@ ix86_handle_regparm_attribute (tree *nod
   return NULL_TREE;
 }
 
+/* Handle a "sseregparm" attribute;
+   arguments as in struct attribute_spec.handler.  */
+static tree
+ix86_handle_sseregparm_attribute (tree *node, tree name,
+				 tree args ATTRIBUTE_UNUSED,
+				 int flags ATTRIBUTE_UNUSED,
+				 bool *no_add_attrs)
+{
+  if (TREE_CODE (*node) != FUNCTION_TYPE
+      && TREE_CODE (*node) != METHOD_TYPE)
+    {
+      warning (OPT_Wattributes, "%qs attribute only applies to functions",
+	       IDENTIFIER_POINTER (name));
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
 /* Return 0 if the attributes for two types are incompatible, 1 if they
    are compatible, and 2 if they are nearly compatible (which causes a
    warning to be generated).  */
@@ -1897,6 +1920,45 @@ ix86_function_regparm (tree type, tree d
   return regparm;
 }
 
+/* Return true, if we can pass up to 8 SFmode and DFmode arguments
+   in SSE registers for a function with the indicated TYPE and DECL.
+   DECL may be NULL when calling function indirectly
+   or considering a libcall.  */
+
+static bool
+ix86_function_sseregparm (tree type, tree decl)
+{
+  /* Use SSE registers to pass SFmode and DFmode arguments if requested
+     by the sseregparm attribute.  */
+  if (type && lookup_attribute ("sseregparm", TYPE_ATTRIBUTES (type)))
+    {
+      if (!TARGET_SSE)
+	{
+	  if (decl)
+	    error ("use of %<sseregparm%> function %qD without SSE enabled",
+		   decl);
+	  else
+	    error ("use of %<sseregparm%> function without SSE enabled");
+	  return false;
+	}
+
+      return true;
+    }
+
+  /* For local functions, pass SFmode (and DFmode for SSE2) arguments
+     in SSE registers even for 32-bit mode and not just 3, but up to
+     8 SSE arguments in registers.  */
+  if (!TARGET_64BIT && decl
+      && TARGET_SSE_MATH && flag_unit_at_a_time && !profile_flag)
+    {
+      struct cgraph_local_info *i = cgraph_local_info (decl);
+      if (i && i->local)
+	return true;
+    }
+
+  return false;
+}
+
 /* Return true if EAX is live at the start of the function.  Used by
    ix86_expand_prologue to determine if we need special help before
    calling allocate_stack_worker.  */
@@ -2053,6 +2115,14 @@ init_cumulative_args (CUMULATIVE_ARGS *c
 	}
     }
 
+  /* Set up the number of SSE registers used for passing SFmode
+     and DFmode arguments.  Warn for mismatching ABI.  */
+  if (ix86_function_sseregparm (fntype, fndecl))
+    {
+      cum->sse_nregs = 8;
+      cum->float_in_sse = true;
+    }
+
   /* Determine if this function has variable arguments.  This is
      indicated by the last argument being 'void_type_mode' if there
      are no variable arguments.  If there are variable arguments, then
@@ -2083,21 +2153,6 @@ init_cumulative_args (CUMULATIVE_ARGS *c
       || (fntype && !TYPE_ARG_TYPES (fntype)))
     cum->maybe_vaarg = true;
 
-  /* For local functions, pass SFmode (and DFmode for SSE2) arguments
-     in SSE registers even for 32-bit mode and not just 3, but up to
-     8 SSE arguments in registers.  */
-  if (!TARGET_64BIT && !cum->maybe_vaarg && !cum->fastcall
-      && cum->sse_nregs == SSE_REGPARM_MAX && fndecl
-      && TARGET_SSE_MATH && flag_unit_at_a_time && !profile_flag)
-    {
-      struct cgraph_local_info *i = cgraph_local_info (fndecl);
-      if (i && i->local)
-	{
-	  cum->sse_nregs = 8;
-	  cum->float_in_sse = true;
-	}
-    }
-
   if (TARGET_DEBUG_ARG)
     fprintf (stderr, ", nregs=%d )\n", cum->nregs);
 
@@ -2775,8 +2830,6 @@ function_arg_advance (CUMULATIVE_ARGS *c
 	  break;
 
 	case DFmode:
-	  if (!TARGET_SSE2)
-	    break;
 	case SFmode:
 	  if (!cum->float_in_sse)
 	    break;
@@ -2904,8 +2957,6 @@ function_arg (CUMULATIVE_ARGS *cum, enum
 	  }
 	break;
       case DFmode:
-	if (!TARGET_SSE2)
-	  break;
       case SFmode:
 	if (!cum->float_in_sse)
 	  break;
@@ -3244,14 +3295,10 @@ ix86_value_regno (enum machine_mode mode
     return 0;
 
   /* Floating point return values in %st(0), except for local functions when
-     SSE math is enabled.  */
-  if (func && SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH
-      && flag_unit_at_a_time)
-    {
-      struct cgraph_local_info *i = cgraph_local_info (func);
-      if (i && i->local)
-	return FIRST_SSE_REG;
-    }
+     SSE math is enabled or for functions with sseregparm attribute.  */
+  if (func && (mode == SFmode || mode == DFmode)
+      && ix86_function_sseregparm (TREE_TYPE (func), func))
+    return FIRST_SSE_REG;
 
   return FIRST_FLOAT_REG;
 }


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