aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKazu Hirata <kazu@codesourcery.com>2007-01-18 19:54:44 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2007-01-18 19:54:44 +0000
commit576c9028f00d275eb9beb66ab2116383759130bb (patch)
treef226a49f2943bd53650b7a718323a484610cf83f
parentdfd050746b226f24b1e4ae35ad06d71ecd77bd04 (diff)
downloadgcc-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/ChangeLog16
-rw-r--r--gcc/calls.c13
-rw-r--r--gcc/config/m68k/linux.h14
-rw-r--r--gcc/config/m68k/m68k.c29
-rw-r--r--gcc/config/m68k/m68k.md3
-rw-r--r--gcc/config/m68k/netbsd-elf.h18
-rw-r--r--gcc/doc/tm.texi7
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