[committed] Fix passing of homogeneous SFmode and DFmode on hppa

Message ID a6c24772-5075-fec3-3661-35f87f74ca23@bell.net
State New
Headers show
Series
  • [committed] Fix passing of homogeneous SFmode and DFmode on hppa
Related show

Commit Message

John David Anglin Feb. 21, 2020, 11:56 p.m.
The attached patch fixes a problem noted in the libffi testsuite.  This is a particular problem
on 32-bit hppa*-hpux*.

We pass homogeneous SFmode and DFmode aggregates in the general registers instead of the floating
point registers that are used to pass SFmode and DFmode values.  ASM_DECLARE_FUNCTION_NAME did not
correctly indicate that the general registers were being used.  The HP linker adjusts the call and
return values to compensate for the registers being used.  Since the indication was wrong, this
resulted in passed and return values being clobbered.

I also adjusted the value size check in pa_function_value as it could accept arguments with a size
other than word or double word.

Tested on hppa2.0w-hp-hpux11.11 and hppa-unknown-linux-gnu.  Committed to trunk, gcc-9 and gcc-8.

Dave

2020-02-21  John David Anglin  <danglin@gcc.gnu.org>

	* gcc/config/pa/pa.c (pa_function_value): Fix check for word and
	double-word size when handling aggregate return values.
	* gcc/config/pa/som.h (ASM_DECLARE_FUNCTION_NAME): Fix to indicate
	that homogeneous SFmode and DFmode aggregates are passed and returned
	in general registers.

Patch

diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 24b88304637..a662de96ac9 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -9335,7 +9335,7 @@  pa_function_value (const_tree valtype,
       HOST_WIDE_INT valsize = int_size_in_bytes (valtype);

       /* Handle aggregates that fit exactly in a word or double word.  */
-      if ((valsize & (UNITS_PER_WORD - 1)) == 0)
+      if (valsize == UNITS_PER_WORD || valsize == 2 * UNITS_PER_WORD)
 	return gen_rtx_REG (TYPE_MODE (valtype), 28);

       if (TARGET_64BIT)
diff --git a/gcc/config/pa/som.h b/gcc/config/pa/som.h
index 95c3bd238fe..505fdd65d79 100644
--- a/gcc/config/pa/som.h
+++ b/gcc/config/pa/som.h
@@ -98,8 +98,8 @@  do {								\

 
 #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
-    do { tree fntype = TREE_TYPE (TREE_TYPE (DECL));			\
-	 tree tree_type = TREE_TYPE (DECL);				\
+    do { tree tree_type = TREE_TYPE (DECL);				\
+	 tree fntype = TREE_TYPE (tree_type);				\
 	 tree parm;							\
 	 int i;								\
 	 if (TREE_PUBLIC (DECL) || TARGET_GAS)				\
@@ -121,9 +121,11 @@  do {								\
 	       {							\
 		 tree type = DECL_ARG_TYPE (parm);			\
 		 machine_mode mode = TYPE_MODE (type);			\
-		 if (mode == SFmode && ! TARGET_SOFT_FLOAT)		\
+		 if (!AGGREGATE_TYPE_P (type)				\
+		     && mode == SFmode && ! TARGET_SOFT_FLOAT)		\
 		   fprintf (FILE, ",ARGW%d=FR", i++);			\
-		 else if (mode == DFmode && ! TARGET_SOFT_FLOAT)	\
+		 else if (!AGGREGATE_TYPE_P (type)			\
+			  && mode == DFmode && ! TARGET_SOFT_FLOAT)	\
 		   {							\
 		     if (i <= 2)					\
 		       {						\
@@ -158,9 +160,13 @@  do {								\
 		 for (; i < 4; i++)					\
 		   fprintf (FILE, ",ARGW%d=GR", i);			\
 	       }							\
-	     if (TYPE_MODE (fntype) == DFmode && ! TARGET_SOFT_FLOAT)	\
+	     if (!AGGREGATE_TYPE_P (fntype)				\
+		 && TYPE_MODE (fntype) == DFmode			\
+		 && ! TARGET_SOFT_FLOAT)				\
 	       fputs (DFMODE_RETURN_STRING, FILE);			\
-	     else if (TYPE_MODE (fntype) == SFmode && ! TARGET_SOFT_FLOAT) \
+	     else if (!AGGREGATE_TYPE_P (fntype)			\
+		      && TYPE_MODE (fntype) == SFmode			\
+		      && ! TARGET_SOFT_FLOAT)				\
 	       fputs (SFMODE_RETURN_STRING, FILE);			\
 	     else if (fntype != void_type_node)				\
 	       fputs (",RTNVAL=GR", FILE);				\