mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-28 21:11:14 +08:00
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
This commit is contained in:
parent
dfd050746b
commit
576c9028f0
@ -1,3 +1,19 @@
|
||||
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
|
||||
|
13
gcc/calls.c
13
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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -124,7 +124,8 @@
|
||||
|
||||
;; Registers by name.
|
||||
(define_constants
|
||||
[(A0_REG 8)
|
||||
[(D0_REG 0)
|
||||
(A0_REG 8)
|
||||
(SP_REG 15)
|
||||
])
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user