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]

[committed] Fix PR target/25731 - complex and vector arguments


In debugging PR target/20754, I noticed that complex and vector float types
were incorrectly being passed in the floating-point argument registers.
In particular, a _Complex float was being passed in the 32-bit runtime
like a double (i.e., it was being packed into the left and right halves
of a double).

The runtime documentations is somewhat ambiguous about how these types
should be passed.  So, I had a contact check with HP how these types
should be passed.  In the 32-bit runtime, they need to be treated in
the same manner as structures and aggregates.  The 64-bit runtime has
a comment about homogenious floating point aggregates but the PA64
compiler treats these objects like regular structures.  Thus, complex
and vector types should be passed in the general registers when they
meet the other constraints.

This patch changes the treatment of complex and vector types so that
they are now treated like structures and aggregates.  Scalar floats
are the only types that can be passed in the floating-point registers.

This change is unfortunately an ABI change and affects calls to
various complex math functions in libm.  This is an issue on linux.

Making this change on 4.1 seems the best time.  There is already an
ABI change under hpux with the introduction of dwarf2 exception support.
I suspect there's an ABI change in libgcc_s in linux as well, although
I'm not sure of the cause.

Tested on hppa-unknown-linux-gnu, hppa2.0w-hp-hpux11.11 and
hppa64-hp-hpux11.11.  Committed to 4.1 and trunk.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

2006-01-18  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	PR target/25731
	* config.gcc (hppa*-*-linux*, hppa[12]*-*-hpux10*, hppa*64*-*-hpux11*,
	hppa[12]*-*-hpux11*): Override default shared libgcc version for both
	sjlj and dwarf2 exception handling.
	* pa/t-hpux-shlib (SHLIB_SOVERSION): New make variable.
	Rework to allow overriding SHLIB_EXT and SHLIB_SOVERSION.
	* pa/pa.c (function_value): Treat complex and vector types as
	aggregates.
	(function_arg): Likewise.  Only pass scalar floats in the floating
	point argument registers.
	* pa/t-slibgcc-dwarf-ver: New file.
	* pa/t-slibgcc-sjlj-ver: New file.
	* pa/t-slibgcc-elf-ver: Delete file.

Index: config.gcc
===================================================================
--- config.gcc	(revision 109693)
+++ config.gcc	(working copy)
@@ -846,10 +846,11 @@
 	tm_file="${tm_file} dbxelf.h elfos.h svr4.h linux.h pa/pa-linux.h \
 		 pa/pa32-regs.h pa/pa32-linux.h"
 	tmake_file="${tmake_file} pa/t-linux"
-	# if not configured with --enable-sjlj-exceptions, bump the
-	# libgcc version number
-	if test x$sjlj != x1; then
-	    tmake_file="$tmake_file pa/t-slibgcc-elf-ver"
+	# Set the libgcc version number
+	if test x$sjlj = x1; then
+	    tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver"
+	else
+	    tmake_file="$tmake_file pa/t-slibgcc-dwarf-ver"
 	fi
 	;;
 # port not yet contributed.
@@ -900,8 +901,11 @@
 	    tmake_file="${tmake_file} pa/t-dce-thr"
 	    ;;
 	esac
-	if test x$sjlj != x1; then
-	    tmake_file="$tmake_file pa/t-slibgcc-elf-ver"
+	# Set the libgcc version number
+	if test x$sjlj = x1; then
+	    tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver"
+	else
+	    tmake_file="$tmake_file pa/t-slibgcc-dwarf-ver"
 	fi
 	use_collect2=yes
 	use_fixproto=yes
@@ -935,8 +939,11 @@
 		       pa/pa-hpux1010.opt pa/pa64-hpux.opt"
 	need_64bit_hwint=yes
 	tmake_file="pa/t-pa64 pa/t-pa-hpux pa/t-hpux-shlib"
-	if test x$sjlj != x1; then
-	    tmake_file="$tmake_file pa/t-slibgcc-elf-ver"
+	# Set the libgcc version number
+	if test x$sjlj = x1; then
+	    tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver"
+	else
+	    tmake_file="$tmake_file pa/t-slibgcc-dwarf-ver"
 	fi
 	extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o"
 	case x${enable_threads} in
@@ -961,8 +968,11 @@
 		;;
 	esac
 	tmake_file="pa/t-pa pa/t-pa-hpux pa/t-hpux-shlib"
-	if test x$sjlj != x1; then
-	    tmake_file="$tmake_file pa/t-slibgcc-elf-ver"
+	# Set the libgcc version number
+	if test x$sjlj = x1; then
+	    tmake_file="$tmake_file pa/t-slibgcc-sjlj-ver"
+	else
+	    tmake_file="$tmake_file pa/t-slibgcc-dwarf-ver"
 	fi
 	case x${enable_threads} in
 	xyes | xposix )
Index: config/pa/t-hpux-shlib
===================================================================
--- config/pa/t-hpux-shlib	(revision 109693)
+++ config/pa/t-hpux-shlib	(working copy)
@@ -1,7 +1,8 @@
 # Build a shared libgcc library.
 SHLIB_EXT = .sl
-SHLIB_NAME = @shlib_base_name@.sl
-SHLIB_SONAME = @shlib_base_name@.1
+SHLIB_NAME = @shlib_base_name@$(SHLIB_EXT)
+SHLIB_SOVERSION = 1
+SHLIB_SONAME = @shlib_base_name@.$(SHLIB_SOVERSION)
 SHLIB_OBJS = @shlib_objs@
 SHLIB_DIR = @multilib_dir@
 SHLIB_SLIBDIR_QUAL = @shlib_slibdir_qual@
@@ -16,7 +17,6 @@
 	mv $(SHLIB_DIR)/$(SHLIB_NAME).tmp $(SHLIB_DIR)/$(SHLIB_NAME) && \
         $(LN_S) $(SHLIB_NAME) $(SHLIB_DIR)/$(SHLIB_SONAME)
 
-
 # $(slibdir) double quoted to protect it from expansion while building
 # libgcc.mk.  We want this delayed until actual install time.
 SHLIB_INSTALL = \
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c	(revision 109693)
+++ config/pa/pa.c	(working copy)
@@ -8791,7 +8791,9 @@
 {
   enum machine_mode valmode;
 
-  if (AGGREGATE_TYPE_P (valtype))
+  if (AGGREGATE_TYPE_P (valtype)
+      || TREE_CODE (valtype) == COMPLEX_TYPE
+      || TREE_CODE (valtype) == VECTOR_TYPE)
     {
       if (TARGET_64BIT)
 	{
@@ -8871,7 +8873,7 @@
      this routine should return zero.  pa_arg_partial_bytes will
      handle arguments which are split between regs and stack slots if
      the ABI mandates split arguments.  */
-  if (! TARGET_64BIT)
+  if (!TARGET_64BIT)
     {
       /* The 32-bit ABI does not split arguments.  */
       if (cum->words + arg_size > max_arg_words)
@@ -8906,7 +8908,9 @@
 	 treatment.  */
       if (arg_size > 1
 	  || mode == BLKmode
-	  || (type && AGGREGATE_TYPE_P (type)))
+	  || (type && (AGGREGATE_TYPE_P (type)
+		       || TREE_CODE (type) == COMPLEX_TYPE
+		       || TREE_CODE (type) == VECTOR_TYPE)))
 	{
 	  /* Double-extended precision (80-bit), quad-precision (128-bit)
 	     and aggregates including complex numbers are aligned on
@@ -8960,8 +8964,13 @@
 	     objects.  The data is right-justified and zero-extended
 	     to 64 bits.  This is opposite to the normal justification
 	     used on big endian targets and requires special treatment.
-	     We now define BLOCK_REG_PADDING to pad these objects.  */
-	  if (mode == BLKmode || (type && AGGREGATE_TYPE_P (type)))
+	     We now define BLOCK_REG_PADDING to pad these objects.
+	     Aggregates, complex and vector types are passed in the same
+	     manner as structures.  */
+	  if (mode == BLKmode
+	      || (type && (AGGREGATE_TYPE_P (type)
+			   || TREE_CODE (type) == COMPLEX_TYPE
+			   || TREE_CODE (type) == VECTOR_TYPE)))
 	    {
 	      rtx loc = gen_rtx_EXPR_LIST (VOIDmode,
 					   gen_rtx_REG (DImode, gpr_reg_base),
@@ -8984,9 +8993,9 @@
        /* If we are doing soft-float with portable runtime, then there
 	  is no need to worry about FP regs.  */
        && !TARGET_SOFT_FLOAT
-       /* The parameter must be some kind of float, else we can just
+       /* The parameter must be some kind of scalar float, else we just
 	  pass it in integer registers.  */
-       && FLOAT_MODE_P (mode)
+       && GET_MODE_CLASS (mode) == MODE_FLOAT
        /* The target function must not have a prototype.  */
        && cum->nargs_prototype <= 0
        /* libcalls do not need to pass items in both FP and general
@@ -9002,7 +9011,7 @@
 	  && !TARGET_GAS
 	  && !cum->incoming
 	  && cum->indirect
-	  && FLOAT_MODE_P (mode)))
+	  && GET_MODE_CLASS (mode) == MODE_FLOAT))
     {
       retval
 	= gen_rtx_PARALLEL
@@ -9025,9 +9034,9 @@
 	      && !TARGET_64BIT
 	      && !TARGET_ELF32
 	      && cum->indirect)
-	  /* If the parameter is not a floating point parameter, then
-	     it belongs in GPRs.  */
-	  || !FLOAT_MODE_P (mode)
+	  /* If the parameter is not a scalar floating-point parameter,
+	     then it belongs in GPRs.  */
+	  || GET_MODE_CLASS (mode) != MODE_FLOAT
 	  /* Structure with single SFmode field belongs in GPR.  */
 	  || (type && AGGREGATE_TYPE_P (type)))
 	retval = gen_rtx_REG (mode, gpr_reg_base);
--- /dev/null	Sat Jan 14 11:32:36 2006
+++ config/pa/t-slibgcc-dwarf-ver	Sat Jan 14 11:36:14 2006
@@ -0,0 +1,3 @@
+# Set the version number of the shared libgcc library (DWARF2 EH).
+
+SHLIB_SOVERSION = 4
--- /dev/null	Sat Jan 14 11:32:36 2006
+++ config/pa/t-slibgcc-sjlj-ver	Sat Jan 14 11:36:42 2006
@@ -0,0 +1,3 @@
+# Set the version number of the shared libgcc library (SJLJ EH).
+
+SHLIB_SOVERSION = 3


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