diff options
author | Kazu Hirata <kazu@codesourcery.com> | 2007-01-18 19:54:44 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2007-01-18 19:54:44 +0000 |
commit | 576c9028f00d275eb9beb66ab2116383759130bb (patch) | |
tree | f226a49f2943bd53650b7a718323a484610cf83f | |
parent | dfd050746b226f24b1e4ae35ad06d71ecd77bd04 (diff) | |
download | gcc-576c9028f00d275eb9beb66ab2116383759130bb.zip gcc-576c9028f00d275eb9beb66ab2116383759130bb.tar.gz gcc-576c9028f00d275eb9beb66ab2116383759130bb.tar.bz2 |
200x-xx-xx Kazu Hirata <kazu@codesourcery.com> Richard Sandiford <richard@codesourcery.com>
gcc/
200x-xx-xx Kazu Hirata <kazu@codesourcery.com>
Richard Sandiford <richard@codesourcery.com>
* doc/tm.texi (TARGET_FUNCTION_VALUE): Expand documentation of
parallels.
* calls.c (expand_call): If the return value is a PARALLEL,
extract its first member.
* config/m68k/linux.h (FUNCTION_EXTRA_EPILOGUE): Remove.
* config/m68k/m68k.c (m68k_output_function_epilogue): Don't
use FUNCTION_EXTRA_EPILOGUE.
(m68k_function_value): Return a PARALLEL if the return value
is of a pointer type.
* config/m68k/netbsd-elf.h (current_function_returns_pointer)
(FUNCTION_EXTRA_EPILOGUE): Remove.
* config/m68k/m68k.md (D0_REG): New constant.
Co-Authored-By: Richard Sandiford <richard@codesourcery.com>
From-SVN: r120929
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/calls.c | 13 | ||||
-rw-r--r-- | gcc/config/m68k/linux.h | 14 | ||||
-rw-r--r-- | gcc/config/m68k/m68k.c | 29 | ||||
-rw-r--r-- | gcc/config/m68k/m68k.md | 3 | ||||
-rw-r--r-- | gcc/config/m68k/netbsd-elf.h | 18 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 7 |
7 files changed, 58 insertions, 42 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 102078d..f433dc5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,20 @@ 2007-01-18 Kazu Hirata <kazu@codesourcery.com> + Richard Sandiford <richard@codesourcery.com> + + * doc/tm.texi (TARGET_FUNCTION_VALUE): Expand documentation of + parallels. + * calls.c (expand_call): If the return value is a PARALLEL, + extract its first member. + * config/m68k/linux.h (FUNCTION_EXTRA_EPILOGUE): Remove. + * config/m68k/m68k.c (m68k_output_function_epilogue): Don't + use FUNCTION_EXTRA_EPILOGUE. + (m68k_function_value): Return a PARALLEL if the return value + is of a pointer type. + * config/m68k/netbsd-elf.h (current_function_returns_pointer) + (FUNCTION_EXTRA_EPILOGUE): Remove. + * config/m68k/m68k.md (D0_REG): New constant. + +2007-01-18 Kazu Hirata <kazu@codesourcery.com> * config/m68k/m68k.c (m68k_output_function_epilogue): Don't output a NOP for empty epilogues. diff --git a/gcc/calls.c b/gcc/calls.c index c0d1f8c..0ca03f8 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -2566,6 +2566,19 @@ expand_call (tree exp, rtx target, int ignore) else valreg = hard_function_value (TREE_TYPE (exp), fndecl, fntype, (pass == 0)); + + /* If VALREG is a PARALLEL whose first member has a zero + offset, use that. This is for targets such as m68k that + return the same value in multiple places. */ + if (GET_CODE (valreg) == PARALLEL) + { + rtx elem = XVECEXP (valreg, 0, 0); + rtx where = XEXP (elem, 0); + rtx offset = XEXP (elem, 1); + if (offset == const0_rtx + && GET_MODE (where) == GET_MODE (valreg)) + valreg = where; + } } /* Precompute all register parameters. It isn't safe to compute anything diff --git a/gcc/config/m68k/linux.h b/gcc/config/m68k/linux.h index cdb8817..2c72d49 100644 --- a/gcc/config/m68k/linux.h +++ b/gcc/config/m68k/linux.h @@ -179,20 +179,6 @@ Boston, MA 02110-1301, USA. */ #define FUNCTION_VALUE(VALTYPE, FUNC) \ m68k_function_value (VALTYPE, FUNC) -/* For compatibility with the large body of existing code which does - not always properly declare external functions returning pointer - types, the m68k/SVR4 convention is to copy the value returned for - pointer functions from a0 to d0 in the function epilogue, so that - callers that have neglected to properly declare the callee can - still find the correct return value. */ - -#define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \ -do { \ - if (current_function_returns_pointer \ - && ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \ - asm_fprintf (FILE, "\tmove.l %Ra0,%Rd0\n"); \ -} while (0); - /* Define how to find the value returned by a library function assuming the value has mode MODE. For m68k/SVR4 look for integer values in d0, pointer values in d0 diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c index 41f61c7..81dded1 100644 --- a/gcc/config/m68k/m68k.c +++ b/gcc/config/m68k/m68k.c @@ -1057,10 +1057,6 @@ m68k_output_function_epilogue (FILE *stream, if (insn && GET_CODE (insn) == BARRIER) return; -#ifdef FUNCTION_EXTRA_EPILOGUE - FUNCTION_EXTRA_EPILOGUE (stream, size); -#endif - fsize = current_frame.size; /* FIXME: leaf_function_p below is too strong. @@ -3894,9 +3890,26 @@ m68k_function_value (tree valtype, tree func ATTRIBUTE_UNUSED) break; } - /* If the function returns a pointer, push that into %a0 */ - if (POINTER_TYPE_P (valtype)) - return gen_rtx_REG (mode, 8); + /* If the function returns a pointer, push that into %a0. */ + if (func && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (func)))) + /* For compatibility with the large body of existing code which + does not always properly declare external functions returning + pointer types, the m68k/SVR4 convention is to copy the value + returned for pointer functions from a0 to d0 in the function + epilogue, so that callers that have neglected to properly + declare the callee can still find the correct return value in + d0. */ + return gen_rtx_PARALLEL + (mode, + gen_rtvec (2, + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (mode, A0_REG), + const0_rtx), + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (mode, D0_REG), + const0_rtx))); + else if (POINTER_TYPE_P (valtype)) + return gen_rtx_REG (mode, A0_REG); else - return gen_rtx_REG (mode, 0); + return gen_rtx_REG (mode, D0_REG); } diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md index b14b3c9..8481fcd 100644 --- a/gcc/config/m68k/m68k.md +++ b/gcc/config/m68k/m68k.md @@ -124,7 +124,8 @@ ;; Registers by name. (define_constants - [(A0_REG 8) + [(D0_REG 0) + (A0_REG 8) (SP_REG 15) ]) diff --git a/gcc/config/m68k/netbsd-elf.h b/gcc/config/m68k/netbsd-elf.h index 234d017..c67f6f8 100644 --- a/gcc/config/m68k/netbsd-elf.h +++ b/gcc/config/m68k/netbsd-elf.h @@ -273,24 +273,6 @@ while (0) m68k_function_value (VALTYPE, FUNC) -/* For compatibility with the large body of existing code which does - not always properly declare external functions returning pointer - types, the m68k/SVR4 convention is to copy the value returned for - pointer functions from a0 to d0 in the function epilogue, so that - callers that have neglected to properly declare the callee can - still find the correct return value. */ - -extern int current_function_returns_pointer; -#define FUNCTION_EXTRA_EPILOGUE(FILE, SIZE) \ -do \ - { \ - if (current_function_returns_pointer \ - && ! find_equiv_reg (0, get_last_insn (), 0, 0, 0, 8, Pmode)) \ - asm_fprintf (FILE, "\tmove.l %Ra0,%Rd0\n"); \ - } \ -while (0) - - /* Define how to find the value returned by a library function assuming the value has mode MODE. For m68k/SVR4 look for integer values in d0, pointer values in d0 diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index dcf7e02..ad70779 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -4107,7 +4107,12 @@ place regardless of mode.) The value of the expression is usually a @code{reg} RTX for the hard register where the return value is stored. The value can also be a @code{parallel} RTX, if the return value is in multiple places. See @code{FUNCTION_ARG} for an explanation of the -@code{parallel} form. +@code{parallel} form. Note that the callee will populate every +location specified in the @code{parallel}, but if the first element of +the @code{parallel} contains the whole return value, callers will use +that element as the canonical location and ignore the others. The m68k +port uses this type of @code{parallel} to return pointers in both +@samp{%a0} (the canonical location) and @samp{%d0}. If @code{TARGET_PROMOTE_FUNCTION_RETURN} returns true, you must apply the same promotion rules specified in @code{PROMOTE_MODE} if |