[revised] Patch to add return_in_msb target hook
Richard Sandiford
rsandifo@redhat.com
Sun Nov 16 19:46:00 GMT 2003
Roger Sayle <roger@eyesopen.com> writes:
> On 16 Nov 2003, Richard Sandiford wrote:
> > ...needs a global or middle-end maintainer!
> >
> > * Makefile.in (expr.o): Depend on $(TARGET_H).
> > * target.h (return_in_msb): New target hook.
> > * target-def.h (TARGET_RETURN_IN_MSB): New macro.
> > (TARGET_CALLS): Include it.
> > * calls.c (shift_returned_value): New function.
> > (expand_call): Use it.
> > * expr.c: Include target.h.
> > (copy_blkmode_from_reg): Check targetm.calls.return_in_msb when
> > deciding what padding is needed. Change the name of the local
> > padding variable from big_endian_correction to padding_correction.
> > * stmt.c (shift_return_value): New function.
> > (expand_return): Use it. Adjust memory->register copy in the same
> > way as copy_blkmode_from_reg. Only change the return register's
> > mode if it was originally BLKmode.
> > * doc/tm.texi (TARGET_RETURN_IN_MSB): Document.
> > * config/mips/mips.c (TARGET_RETURN_IN_MSB): Define.
> > (mips_fpr_return_fields): New, split out from mips_function_value.
> > (mips_return_in_msb, mips_return_fpr_pair): New functions.
> > (mips_function_value): Rework to use the functions above.
> > * config/mips/irix6-libc-compat.c: Delete.
> > * config/mips/t-iris6 (LIB2FUNCS_STATIC_EXTRA): Undefine.
>
> This is OK for mainline.
Thanks Roger! Much appreciated. ;)
For the record, I've committed the patch and the following update to the
web pages, which Gerald approved here:
http://gcc.gnu.org/ml/gcc-patches/2003-09/msg01414.html
I've made the change he suggested (including more text in the
"has changed" link).
Richard
Index: htdocs/gcc-3.4/changes.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-3.4/changes.html,v
retrieving revision 1.67
diff -c -p -d -r1.67 changes.html
*** htdocs/gcc-3.4/changes.html 16 Nov 2003 14:22:49 -0000 1.67
--- htdocs/gcc-3.4/changes.html 16 Nov 2003 19:36:45 -0000
***************
*** 32,40 ****
in this release</a>.</li>
<li>GCC now requires an ISO C90 (ANSI C89) C compiler to build.
K&R C compilers will not work.</li>
! <li>On some MIPS targets, the code generated by this release
! will not be binary compatible with previous releases.
! See <a href="#mips_abi">below</a> for details.</li>
<li>The configure option <code>--enable-threads=pthreads</code> has
been removed; use <code>--enable-threads=posix</code> instead,
which should have the same effect.</li>
--- 32,40 ----
in this release</a>.</li>
<li>GCC now requires an ISO C90 (ANSI C89) C compiler to build.
K&R C compilers will not work.</li>
! <li>The implementation of the <a href="mips-abi.html">MIPS ABIs has
! changed</a>. As a result, the code generated for certain MIPS
! targets will not be binary compatible with earlier releases.</li>
<li>The configure option <code>--enable-threads=pthreads</code> has
been removed; use <code>--enable-threads=posix</code> instead,
which should have the same effect.</li>
***************
*** 413,431 ****
and should work with any MIPS I (<code>mips-*</code>) or MIPS III
(<code>mips64-*</code>) configuration.</li>
! <li><a name="mips_abi">n32 and n64 MIPS targets now pass all
! structures by value.</a> While this change brings GCC closer
! to ABI compliance, it will unfortunately break binary compatibility
! with earlier releases. A structure used to be passed by reference if:
! <ul>
! <li>the target was big-endian;</li>
! <li>the structure was bigger than 8 bytes;</li>
! <li>the structure's size was not a multiple of 8 bytes; and</li>
! <li>the first word of the structure would have been passed in
! a register.</li>
! </ul>
! Note that only big-endian n32 & n64 targets (such as IRIX 6) are
! affected.</li>
</ul>
<h4>SuperH</h4>
--- 413,421 ----
and should work with any MIPS I (<code>mips-*</code>) or MIPS III
(<code>mips64-*</code>) configuration.</li>
! <li>Several <a href="mips-abi.html">ABI bugs in the MIPS port</a>
! have been fixed. Unfortunately, these changes will break binary
! compatibility with earlier releases.</li>
</ul>
<h4>SuperH</h4>
Index: htdocs/gcc-3.4/mips-abi.html
===================================================================
RCS file: htdocs/gcc-3.4/mips-abi.html
diff -N htdocs/gcc-3.4/mips-abi.html
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- htdocs/gcc-3.4/mips-abi.html 16 Nov 2003 19:36:45 -0000
***************
*** 0 ****
--- 1,346 ----
+ <html>
+
+ <head>
+ <title>MIPS ABI Changes in GCC 3.4</title>
+ </head>
+
+ <body>
+
+ <h1>MIPS ABI Changes in GCC 3.4</h1>
+
+ <p>GCC 3.4 fixes several cases in which earlier releases would not
+ follow the MIPS calling conventions. This document describes
+ each fix and the kind of code it will affect. In each case,
+ GCC 3.4 will not be binary compatible with earlier releases.</p>
+
+ <p>Most of the fixes are related to the handling of structure
+ and union types. In the summary below, "aggregate" refers
+ to both structures and unions.</p>
+
+ <p>Note that IRIX 6 configurations used to work around
+ <a href="#B">B</a> and <a href="#E">E</a> by providing wrappers
+ for certain libc functions. These wrappers are not needed for 3.4
+ and have been removed. It should be possible to link code generated
+ by GCC 3.4 directly with code generated by SGI's compilers.</p>
+
+ <h2>A. Small aggregate arguments (1)</h2>
+
+ <table cellpadding="4">
+ <tr valign="top">
+ <th align="right">Affected ABIs</th>
+ <td>o32</th>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Endianness</th>
+ <td>little</th>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Conditions</th>
+ <td><ul>
+ <li>An aggregate argument is passed in a register; and</li>
+ <li>that argument is smaller than 4 bytes.</li>
+ </ul></td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Old behavior</th>
+ <td>The register was padded at the least significant end.</td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">New behavior</th>
+ <td>The register is padded at the most significant end.</td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Example</th>
+ <td><pre>struct s { char c[2]; };
+ void f (struct s x);</pre>
+
+ <p><code>x</code> is passed in argument register <code>$4</code>,
+ which is laid out as follows:</p>
+
+ <table cellpadding="4">
+ <tr align="center">
+ <th></th> <th>7-0</th> <th>15-8</th> <th>23-16</th> <th>31-24</th>
+ </tr>
+
+ <tr align="center">
+ <th align="left">Old behavior</td>
+ <td>padding</td> <td>padding</td> <td>c[0]</td> <td>c[1]</td>
+ </tr>
+
+ <tr align="center">
+ <th align="left">New behavior</td>
+ <td>c[0]</td> <td>c[1]</td> <td>padding</td> <td>padding</td>
+ </tr>
+ </table></td>
+ </tr>
+ </table>
+
+ <h2><a name="B">B. Small aggregate arguments (2)</a></h2>
+
+ <table cellpadding="4">
+ <tr valign="top">
+ <th align="right">Affected ABIs</th>
+ <td>n32 and n64</th>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Endianness</th>
+ <td>big</th>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Conditions</th>
+ <td><ul>
+ <li>An aggregate argument is passed in a register; and</li>
+ <li>that argument is smaller than 8 bytes.</li>
+ </ul></td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Old behavior</th>
+ <td>The register was padded at the most significant end.</td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">New behavior</th>
+ <td>The register is padded at the least significant end.</td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Example</th>
+ <td><pre>struct s { char c[2]; };
+ void f (struct s x);</pre>
+
+ <p><code>x</code> is passed in argument register
+ <code>$4</code>, which is laid out as follows:</p>
+
+ <table cellpadding="4">
+ <tr align="center">
+ <th></th>
+ <th>63-56</th> <th>55-48</th> <th>47-40</th> <th>39-32</th>
+ <th>31-24</th> <th>23-16</th> <th>15-8</th> <th>7-0</th>
+ </tr>
+
+ <tr align="center">
+ <th align="left">Old behavior</td>
+ <td>padding</td> <td>padding</td> <td>padding</td> <td>padding</td>
+ <td>padding</td> <td>padding</td> <td>c[0]</td> <td>c[1]</td>
+ </tr>
+
+ <tr align="center">
+ <th align="left">New behavior</td>
+ <td>c[0]</td> <td>c[1]</td> <td>padding</td> <td>padding</td>
+ <td>padding</td> <td>padding</td> <td>padding</td> <td>padding</td>
+ </tr>
+ </table></td>
+ </tr>
+ </table>
+
+ <h2>C. Large aggregate arguments</h2>
+
+ <table cellpadding="4">
+ <tr valign="top">
+ <th align="right">Affected ABIs</th>
+ <td>n32 and n64</th>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Endianness</th>
+ <td>either</th>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Conditions</th>
+ <td><ul>
+ <li>An aggregate argument is passed to a function;</li>
+ <li>the aggregate's size is not a multiple of 8 bytes; and</li>
+ <li>there are enough argument registers to hold some of
+ the aggregate, but not enough to hold all of it.</li>
+ </ul></td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Old behavior</th>
+ <td>The argument was passed by reference.</td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">New behavior</th>
+ <td>The argument is passed by value.</td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Example</th>
+ <td><pre>struct s { int i[17]; };
+ void f (struct s x);</pre>
+
+ <p>It would take 9 registers to hold <code>x</code>, but
+ only 8 argument registers are available. Since <code>x</code>'s
+ size is not a multiple of 8, previous releases passed it by
+ reference (that is, they passed a pointer to <code>x</code>
+ in <code>$4</code>).</p>
+
+ <p>The new behavior is to pass <code>x</code> by value.
+ The first 8 words are passed in argument registers and
+ the last is passed on the stack.</p></td>
+ </tr>
+ </table>
+
+ <h2>D. Single-field structure arguments</h2>
+
+ <table cellpadding="4">
+ <tr valign="top">
+ <th align="right">Affected ABIs</th>
+ <td>o32, o64, n32 and n64</th>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Endianness</th>
+ <td>either</th>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Conditions</th>
+ <td><ul>
+ <li>A structure containing a single field is passed by value;
+ and</li>
+ <li>that field has a floating-point type.</li>
+ </ul></td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Old behavior</th>
+ <td>The structure was treated like a scalar value of the same
+ floating-point type. For example, a structure containing a
+ <code>float</code> field was treated in the same way as a
+ scalar <code>float</code> value.</td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">New behavior</th>
+ <td>There is no special treatment for such structures.
+ Note however that the usual n32 and n64 rules still hold:
+ naturally-aligned fields of type <code>double</code> are
+ passed in floating-point registers.</td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Example</th>
+ <td><pre>struct s { float f; };
+ void f (struct s x);</pre>
+
+ <p>GCC used to pass <code>x</code> in <code>$f12</code>.
+ Now it passes it in <code>$4</code>, just like any other
+ structure.</p></td>
+ </tr>
+ </table>
+
+ <h2><a name="E">E. Structure return values</a></h2>
+
+ <table cellpadding="4">
+ <tr valign="top">
+ <th align="right">Affected ABIs</th>
+ <td>n32 and n64</th>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Endianness</th>
+ <td>big</th>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Conditions</th>
+ <td><ul>
+ <li>An aggregate is returned by value;</li>
+ <li>that aggregate is smaller than 16 bytes;</li>
+ <li>its size is not a multiple of 8 bytes; and</li>
+ <li>if it is a structure, either:
+ <ol>
+ <li>it has more than two fields; or</li>
+ <li>it has at least one non-floating-point field.</li>
+ </ol></li>
+ </ul></td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Old behavior</th>
+ <td>The return register was padded at the most significant end.</td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">New behavior</th>
+ <td>The return register is padded at the least significant end.</td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Example</th>
+ <td><pre>struct s { char c[3]; };
+ struct s f ();</pre>
+
+ <p>f() returns its value in <code>$2</code>, which is laid
+ out as follows:</p>
+
+ <table cellpadding="4">
+ <tr align="center">
+ <th></th>
+ <th>63-56</th> <th>55-48</th> <th>47-40</th> <th>39-32</th>
+ <th>31-24</th> <th>23-16</th> <th>15-8</th> <th>7-0</th>
+ </tr>
+
+ <tr align="center">
+ <th align="left">Old behavior</td>
+ <td>padding</td> <td>padding</td> <td>padding</td> <td>padding</td>
+ <td>padding</td> <td>c[0]</td> <td>c[1]</td> <td>c[2]</td>
+ </tr>
+
+ <tr align="center">
+ <th align="left">New behavior</td>
+ <td>c[0]</td> <td>c[1]</td> <td>c[2]</td> <td>padding</td>
+ <td>padding</td> <td>padding</td> <td>padding</td> <td>padding</td>
+ </tr>
+ </table></td>
+ </tr>
+ </table>
+
+ <h2>F. Complex return values</h2>
+
+ <table cellpadding="4">
+ <tr valign="top">
+ <th align="right">Affected ABIs</th>
+ <td>n32 and n64</th>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Endianness</th>
+ <td>either</th>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Conditions</th>
+ <td>A function returns a complex <code>float</code> or
+ <code>double</code>.</td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Old behavior</th>
+ <td>The value was returned in <code>$f0</code> and <code>$f1</code>.</td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">New behavior</th>
+ <td>The value is returned in <code>$f0</code> and <code>$f2</code>.</td>
+ </tr>
+
+ <tr valign="top">
+ <th align="right">Example</th>
+ <td><pre>_Complex float f ();</pre></td>
+ </tr>
+ </table>
+
+ </body>
+ </html>
More information about the Gcc-patches
mailing list