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] Fix incorrect PowerPC-64 AltiVec ABI


Hello,

the ppc64_sysv_abi_push_dummy_call routine contains the following comment:

             /* In the Altivec ABI, vectors go in the vector
                registers v2 .. v13, or when that runs out, a vector
                annex which goes above all the normal parameters.
                NOTE: cagney/2003-09-21: This is a guess based on the
                PowerOpen Altivec ABI.  */

However, this does not in fact correctly describe the current PowerPC-64
AltiVec vector ABI.  According to the 1.9 version of the ABI document,
which agrees to what GCC actually implements, vector argument are treated
similarly to float arguments, in that they go both into the *regular*
parameter area (not a special "vector annex") and the vector registers
(as long as any are available).

Now, the gdb.arch/altivec-abi.c test case is supposed to test correct
implementation of the ABI, and it even makes sure to include a parameter
that overflows registers and must therefore be retrieved from the
parameter area on the stack.  Unfortunately, the test case does not
actually make any use of that parameter, and therefore does not
notice GDB's implementation is broken.

The following patch implements the correct vector ABI on PowerPC-64,
and updates the test case to at least check this case.

Tested on powerpc64-linux with no regressions.

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

Bye,
Ulrich



ChangeLog:

	* ppc-sysv-tdep.c (ppc64_sysv_abi_push_dummy_call): Implement
	correct ABI for AltiVec vector arguments.

testsuite/ChangeLog:

	* gdb.arch/altivec-abi.c (vec_func): Make use of intv_on_stack_f
	when computing result.
	* gdb.arch/altivec-abi.exp: Update expected results.


Index: gdb/ppc-sysv-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-sysv-tdep.c,v
retrieving revision 1.60
diff -u -p -r1.60 ppc-sysv-tdep.c
--- gdb/ppc-sysv-tdep.c	11 Jan 2011 15:10:01 -0000	1.60
+++ gdb/ppc-sysv-tdep.c	1 Feb 2011 17:29:32 -0000
@@ -902,9 +902,6 @@ ppc64_sysv_abi_push_dummy_call (struct g
   ULONGEST back_chain;
   /* See for-loop comment below.  */
   int write_pass;
-  /* Size of the Altivec's vector parameter region, the final value is
-     computed in the for-loop below.  */
-  LONGEST vparam_size = 0;
   /* Size of the general parameter region, the final value is computed
      in the for-loop below.  */
   LONGEST gparam_size = 0;
@@ -948,28 +945,21 @@ ppc64_sysv_abi_push_dummy_call (struct g
       /* Next available vector register for vector arguments.  */
       int vreg = 2;
       /* The address, at which the next general purpose parameter
-         (integer, struct, float, ...) should be saved.  */
+         (integer, struct, float, vector, ...) should be saved.  */
       CORE_ADDR gparam;
-      /* Address, at which the next Altivec vector parameter should be
-         saved.  */
-      CORE_ADDR vparam;
 
       if (!write_pass)
 	{
-	  /* During the first pass, GPARAM and VPARAM are more like
-	     offsets (start address zero) than addresses.  That way
-	     they accumulate the total stack space each region
-	     requires.  */
+	  /* 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.  */
 	  gparam = 0;
-	  vparam = 0;
 	}
       else
 	{
-	  /* Decrement the stack pointer making space for the Altivec
-	     and general on-stack parameters.  Set vparam and gparam
-	     to their corresponding regions.  */
-	  vparam = align_down (sp - vparam_size, 16);
-	  gparam = align_down (vparam - gparam_size, 16);
+	  /* Decrement the stack pointer making space for the on-stack
+	     stack parameters.  Set gparam to that region.  */
+	  gparam = align_down (sp - 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);
@@ -1147,24 +1137,25 @@ ppc64_sysv_abi_push_dummy_call (struct g
 		   && TYPE_CODE (type) == TYPE_CODE_ARRAY
 		   && tdep->ppc_vr0_regnum >= 0)
 	    {
-	      /* In the Altivec ABI, vectors go in the vector
-	         registers v2 .. v13, or when that runs out, a vector
-	         annex which goes above all the normal parameters.
-	         NOTE: cagney/2003-09-21: This is a guess based on the
-	         PowerOpen Altivec ABI.  */
-	      if (vreg <= 13)
+	      /* In the Altivec ABI, vectors go in the vector registers
+		 v2 .. v13, as well as the parameter area -- always at
+		 16-byte aligned addresses.  */
+
+	      gparam = align_up (gparam, 16);
+	      greg += greg & 1;
+
+	      if (write_pass)
 		{
-		  if (write_pass)
+		  if (vreg <= 13)
 		    regcache_cooked_write (regcache,
 					   tdep->ppc_vr0_regnum + vreg, val);
-		  vreg++;
-		}
-	      else
-		{
-		  if (write_pass)
-		    write_memory (vparam, val, TYPE_LENGTH (type));
-		  vparam = align_up (vparam + TYPE_LENGTH (type), 16);
+
+		  write_memory (gparam, val, TYPE_LENGTH (type));
 		}
+
+	      greg += 2;
+	      vreg++;
+	      gparam += 16;
 	    }
 	  else if ((TYPE_CODE (type) == TYPE_CODE_INT
 		    || TYPE_CODE (type) == TYPE_CODE_ENUM
@@ -1307,9 +1298,8 @@ ppc64_sysv_abi_push_dummy_call (struct g
 
       if (!write_pass)
 	{
-	  /* Save the true region sizes ready for the second pass.  */
-	  vparam_size = vparam;
-	  /* Make certain that the general parameter save area is at
+	  /* Save the true region sizes ready for the second pass.
+	     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;
Index: gdb/testsuite/gdb.arch/altivec-abi.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.arch/altivec-abi.c,v
retrieving revision 1.1
diff -u -p -r1.1 altivec-abi.c
--- gdb/testsuite/gdb.arch/altivec-abi.c	14 May 2002 22:02:52 -0000	1.1
+++ gdb/testsuite/gdb.arch/altivec-abi.c	1 Feb 2011 17:29:33 -0000
@@ -71,7 +71,7 @@ vec_func (vector short vshort_f,        
    vector unsigned char vuchar_res;
 
    vint_res  = vec_add (vint_f, intv_on_stack_f);
-   vint_res  = vec_add (vint_f, y_f);
+   vint_res  = vec_add (vint_res, y_f);
    vuint_res  = vec_add (vuint_f, ((vector unsigned int) {5,6,7,8}));
    vshort_res  = vec_add (vshort_f, x_f);
    vushort_res  = vec_add (vushort_f,
Index: gdb/testsuite/gdb.arch/altivec-abi.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.arch/altivec-abi.exp,v
retrieving revision 1.23
diff -u -p -r1.23 altivec-abi.exp
--- gdb/testsuite/gdb.arch/altivec-abi.exp	1 Jan 2011 15:33:40 -0000	1.23
+++ gdb/testsuite/gdb.arch/altivec-abi.exp	1 Feb 2011 17:29:33 -0000
@@ -91,7 +91,8 @@ proc altivec_abi_tests { extra_flags for
     # the last one will go on the stack.
     set msg "call inferior function with vectors (1)"
     gdb_test "p vec_func(vshort,vushort,vint,vuint,vchar,vuchar,vfloat,x,y,a,b,c,intv_on_stack)" \
-	".\[0-9\]+ = .2, 2, 2, 2." "call inferior function with vectors (1)"
+	".\[0-9\]+ = .14, 36, 58, 80." "call inferior function with vectors (1)"
+
 
     # Let's call the function again with dummy arguments.  This is to clean
     # up the contents of the vector registers before the next call.
@@ -114,7 +115,7 @@ proc altivec_abi_tests { extra_flags for
 	"step into vec_fun"
 
     set pattern2 $pattern
-    append pattern2 " at.*altivec-abi.c.*main.*result = vec_func .vshort,.*goes in v2.*Value returned is.*= .2, 2, 2, 2."
+    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" \
-- 
  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]