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]

Another ABI correction on SPARC


While investigating calling conventions for vector types on SPARC, I realized 
that both the 32-bit and the 64-bit ABIs have a nice property: an argument 
that is passed in registers can never occupy more than 2 word-equivalent 
registers (aka slots).  Otherwise it is passed in memory.

And of course there is one exception: a '_Complex long long' argument is 
passed by value in 32-bit mode.  This means that it spans 4 of the 6 
integers registers used for argument passing, which is dumb.

Given that the 3.4 branch already changed the ABI for complex floating-point 
types in 32-bit mode, I think this change is worth adding too.

Compiled, regtested and compat-regtested on sparc-sun-solaris2.8.  Applied to 
mainline and 3.4 branch.


2004-02-04  Eric Botcazou  <ebotcazou@libertysurf.fr>

	* config/sparc/sparc.c (function_arg_pass_by_reference): Return 1
	for all modes whose size is greater than 8 bytes if ARCH32.
	(sparc_va_arg): Handle all modes whose size is greater than 8 bytes
	by reference if ARCH32.


-- 
Eric Botcazou
Index: config/sparc/sparc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.c,v
retrieving revision 1.271.4.10
diff -u -p -r1.271.4.10 sparc.c
--- config/sparc/sparc.c	2 Feb 2004 12:24:20 -0000	1.271.4.10
+++ config/sparc/sparc.c	4 Feb 2004 17:58:41 -0000
@@ -5596,10 +5596,8 @@ function_arg_pass_by_reference (const st
   if (TARGET_ARCH32)
     {
       return ((type && AGGREGATE_TYPE_P (type))
-	      || mode == TFmode
 	      || mode == SCmode
-	      || mode == DCmode
-	      || mode == TCmode);
+	      || GET_MODE_SIZE (mode) > 8);
     }
   else
     {
@@ -5810,10 +5808,8 @@ sparc_va_arg (tree valist, tree type)
   else
     {
       if (AGGREGATE_TYPE_P (type)
-	  || TYPE_MODE (type) == TFmode
 	  || TYPE_MODE (type) == SCmode
-	  || TYPE_MODE (type) == DCmode
-	  || TYPE_MODE (type) == TCmode)
+	  || GET_MODE_SIZE (TYPE_MODE (type)) > 8)
 	{
 	  indirect = 1;
 	  size = rsize = UNITS_PER_WORD;
Index: gcc-3.4/sparc-abi.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-3.4/sparc-abi.html,v
retrieving revision 1.2
diff -u -r1.2 sparc-abi.html
--- gcc-3.4/sparc-abi.html	3 Feb 2004 06:46:35 -0000	1.2
+++ gcc-3.4/sparc-abi.html	4 Feb 2004 18:48:48 -0000
@@ -352,7 +352,39 @@
   </tr>
 </table>
 
-<h2>H. Complex integral arguments (GCC extension)</h2>
+<h2>H. Complex integral arguments (GCC extension) (1)</h2>
+
+<table cellpadding="4">
+  <tr valign="top">
+    <th align="right">Affected&nbsp;ABI</th>
+    <td>32-bit</td>
+  </tr>
+
+  <tr valign="top">
+    <th align="right">Conditions</th>
+    <td>A <code>_Complex long long</code> value is passed to a function.</td>
+  </tr>
+
+  <tr valign="top">
+    <th align="right">Old&nbsp;behavior</th>
+    <td>The <code>_Complex long long</code> value was passed in registers.</td>
+  </tr>
+
+  <tr valign="top">
+    <th align="right">New&nbsp;behavior</th>
+    <td>The <code>_Complex long long</code> value is passed in memory.</td>
+  </tr>
+
+  <tr valign="top">
+    <th align="right">Example</th>
+    <td><pre>void g (_Complex long long x1);</pre>
+
+        <p><code>x1</code> (its address) is passed in register <code>%o0</code>,
+	   instead of <code>%o0-%o3</code>.</p></td>
+  </tr>
+</table>
+
+<h2>I. Complex integral arguments (GCC extension) (2)</h2>
 
 <table cellpadding="4">
   <tr valign="top">

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