This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB 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]

[rfc, ppc64] Support "generic" vector ABI


Hello,

the altivec-abi.exp test case results in a number of failures for
the "generic" variant on 64-bit PowerPC Linux, when using a current
compiler (4.3 or newer).

It turns out this is because ppc-sysv-tdep.c actually does not
support "generic" vectors at all for the 64-bit case; it always
treats all vectors as AltiVec.

This used to work, because GCC 4.1 and 4.2 likewise had a bug that
made -mabi=no-altivec a complete no-op: even in the presence of
this flag, the compiler would treat vectors as AltiVec.

Now this has been fixed with GCC 4.3, see the bugzilla:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34526
which causes GDB to fail on those cases now.


The following patch adds support for "generic" vectors in ppc64,
as implemented by GCC versions >= 4.3.  Since this would now
cause failures on GCC 4.1 or 4.2, I've added a check in the
test case to skip the "generic" tests on those compilers.

I've also added an additional run "generic ABI, auto" to better
test automatic detection on 32-bit; this used to be redundant
since the GCC would default to the generic case, but the GCC
patch refered to above also changed the 32-bit default to
-mabi=altivec.  The additional test now makes sure both
generic and AltiVec cases are tested, no matter what the
GCC default is.


Note that in the 64-bit generic case, vectors are returned by
reference.  This caused three failures in the test suite; two
of them are fixed by this additional patch:
http://sourceware.org/ml/gdb-patches/2011-03/msg00687.html
and the final one is resolved by changing the test, see below.


Tested with no regressions on powerpc64-linux with -m32 and -m64,
both on a GCC 4.1 and a GCC 4.4 based system.

Any comments?  I'm planning to commit this in a couple of days ...

Bye,
Ulrich


ChangeLog:

gdb/
	* ppc-sysv-tdep.c (ppc64_sysv_abi_push_dummy_call): Add support
	for the "generic" vector ABI used with GCC 4.3 and later.
	(ppc64_sysv_abi_return_value): Likewise.

gdb/testsuite:
	* gdb.arch/altivec-abi.exp: Skip "generic" tests on 64-bit when
	using a GCC 4.1 or 4.2 compiler.  Add an additional test variant
	"generic ABI, auto".
	(altivec_abi_tests): Accept vectors returned by reference.


Index: gdb/ppc-sysv-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-sysv-tdep.c,v
retrieving revision 1.62
diff -u -p -r1.62 ppc-sysv-tdep.c
--- gdb/ppc-sysv-tdep.c	8 Feb 2011 13:30:08 -0000	1.62
+++ gdb/ppc-sysv-tdep.c	11 Mar 2011 20:25:04 -0000
@@ -1119,6 +1119,9 @@ ppc64_sysv_abi_push_dummy_call (struct g
   ULONGEST back_chain;
   /* See for-loop comment below.  */
   int write_pass;
+  /* Size of the by-reference parameter copy region, the final value is
+     computed in the for-loop below.  */
+  LONGEST refparam_size = 0;
   /* Size of the general parameter region, the final value is computed
      in the for-loop below.  */
   LONGEST gparam_size = 0;
@@ -1171,19 +1174,26 @@ ppc64_sysv_abi_push_dummy_call (struct g
       /* The address, at which the next general purpose parameter
          (integer, struct, float, vector, ...) should be saved.  */
       CORE_ADDR gparam;
+      /* The address, at which the next by-reference parameter
+	 (non-Altivec vector, variably-sized type) should be saved.  */
+      CORE_ADDR refparam;
 
       if (!write_pass)
 	{
-	  /* During the first pass, GPARAM is more like an offset
-	     (start address zero) than an address.  That way it
-	     accumulates the total stack space required.  */
+	  /* During the first pass, GPARAM and REFPARAM are more like
+	     offsets (start address zero) than addresses.  That way
+	     they accumulate the total stack space each region
+	     requires.  */
 	  gparam = 0;
+	  refparam = 0;
 	}
       else
 	{
-	  /* Decrement the stack pointer making space for the on-stack
-	     stack parameters.  Set gparam to that region.  */
-	  gparam = align_down (sp - gparam_size, 16);
+	  /* Decrement the stack pointer making space for the Altivec
+	     and general on-stack parameters.  Set refparam and gparam
+	     to their corresponding regions.  */
+	  refparam = align_down (sp - refparam_size, 16);
+	  gparam = align_down (refparam - gparam_size, 16);
 	  /* Add in space for the TOC, link editor double word,
 	     compiler double word, LR save area, CR save area.  */
 	  sp = align_down (gparam - 48, 16);
@@ -1462,7 +1472,7 @@ ppc64_sysv_abi_push_dummy_call (struct g
 	    }
 	  else if (TYPE_LENGTH (type) == 16 && TYPE_VECTOR (type)
 		   && TYPE_CODE (type) == TYPE_CODE_ARRAY
-		   && tdep->ppc_vr0_regnum >= 0)
+		   && tdep->vector_abi == POWERPC_VEC_ALTIVEC)
 	    {
 	      /* In the Altivec ABI, vectors go in the vector registers
 		 v2 .. v13, as well as the parameter area -- always at
@@ -1484,6 +1494,30 @@ ppc64_sysv_abi_push_dummy_call (struct g
 	      vreg++;
 	      gparam += 16;
 	    }
+	  else if (TYPE_LENGTH (type) >= 16 && TYPE_VECTOR (type)
+		   && TYPE_CODE (type) == TYPE_CODE_ARRAY)
+	    {
+	      /* Non-Altivec vectors are passed by reference.  */
+
+	      /* Copy value onto the stack ...  */
+	      refparam = align_up (refparam, 16);
+	      if (write_pass)
+		write_memory (refparam, val, TYPE_LENGTH (type));
+
+	      /* ... and pass a pointer to the copy as parameter.  */
+	      if (write_pass)
+		{
+		  if (greg <= 10)
+		    regcache_cooked_write_unsigned (regcache,
+						    tdep->ppc_gp0_regnum +
+						    greg, refparam);
+		  write_memory_unsigned_integer (gparam, tdep->wordsize,
+						 byte_order, refparam);
+		}
+	      greg++;
+	      gparam = align_up (gparam + tdep->wordsize, tdep->wordsize);
+	      refparam = align_up (refparam + TYPE_LENGTH (type), tdep->wordsize);
+	    }
 	  else if ((TYPE_CODE (type) == TYPE_CODE_INT
 		    || TYPE_CODE (type) == TYPE_CODE_ENUM
 		    || TYPE_CODE (type) == TYPE_CODE_BOOL
@@ -1625,8 +1659,9 @@ ppc64_sysv_abi_push_dummy_call (struct g
 
       if (!write_pass)
 	{
-	  /* Save the true region sizes ready for the second pass.
-	     Make certain that the general parameter save area is at
+	  /* Save the true region sizes ready for the second pass.  */
+	  refparam_size = refparam;
+	  /* Make certain that the general parameter save area is at
 	     least the minimum 8 registers (or doublewords) in size.  */
 	  if (greg < 8)
 	    gparam_size = 8 * tdep->wordsize;
@@ -1849,7 +1884,8 @@ ppc64_sysv_abi_return_value (struct gdba
 	}
       /* A VMX vector is returned in v2.  */
       if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY
-        && TYPE_VECTOR (valtype) && tdep->ppc_vr0_regnum >= 0)
+	  && TYPE_VECTOR (valtype)
+	  && tdep->vector_abi == POWERPC_VEC_ALTIVEC)
         {
           if (readbuf)
             regcache_cooked_read (regcache, tdep->ppc_vr0_regnum + 2, readbuf);
Index: gdb/testsuite/gdb.arch/altivec-abi.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.arch/altivec-abi.exp,v
retrieving revision 1.24
diff -u -p -r1.24 altivec-abi.exp
--- gdb/testsuite/gdb.arch/altivec-abi.exp	8 Feb 2011 13:25:01 -0000	1.24
+++ gdb/testsuite/gdb.arch/altivec-abi.exp	11 Mar 2011 20:25:04 -0000
@@ -118,8 +118,17 @@ proc altivec_abi_tests { extra_flags for
     append pattern2 " at.*altivec-abi.c.*main.*result = vec_func .vshort,.*goes in v2.*Value returned is.*= .14, 36, 58, 80."
 
     # Let's see if the result is returned correctly.
-    gdb_test "finish" "Run till exit from .0.*$pattern2" \
-	"vector value returned correctly"
+    set message "vector value returned correctly"
+    gdb_test_multiple "finish" $message {
+	-re "Run till exit from .0.*$pattern2.*$gdb_prompt $" {
+	    pass $message
+	}
+	-re "Run till exit from .0.*Cannot determine contents.*$gdb_prompt $" {
+	    # This happens in those cases where the vector is returned by
+	    # reference (generic vectors on 64-bit GNU/Linux).
+	    pass $message
+	}
+    }
 
     # can we print the args correctly for this function?
     gdb_test "break struct_of_vector_func" "" ""
@@ -150,9 +159,17 @@ if [test_compiler_info gcc*] {
     # On GNU/Linux, we can mix -mabi=no-altivec and -mabi=altivec.
     # So test some combinations.
     if { [istarget "powerpc*-linux*"] } {
-	set binfile ${objdir}/${subdir}/${testfile}-ge-ge
-	set pf_prefix "${saved_prefix} generic ABI, forced:"
-	altivec_abi_tests "additional_flags=-maltivec additional_flags=-mabi=no-altivec" "generic"
+	# On 64-bit GNU/Linux with GCC 4.1 and 4.2, -mabi=no-altivec
+	# was broken, so skip those tests there.
+	if { ![is_lp64_target] || ![test_compiler_info "gcc-4-\[12\]-*"] } {
+	    set binfile ${objdir}/${subdir}/${testfile}-ge-ge
+	    set pf_prefix "${saved_prefix} generic ABI, forced:"
+	    altivec_abi_tests "additional_flags=-maltivec additional_flags=-mabi=no-altivec" "generic"
+
+	    set binfile ${objdir}/${subdir}/${testfile}-ge-auto
+	    set pf_prefix "${saved_prefix} generic ABI, auto:"
+	    altivec_abi_tests "additional_flags=-maltivec additional_flags=-mabi=no-altivec" "auto"
+	}
 
 	set binfile ${objdir}/${subdir}/${testfile}-av-av
 	set pf_prefix "${saved_prefix} AltiVec ABI, forced:"
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


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