aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMaxim Kuvyrkov <mkuvyrkov@gcc.gnu.org>2009-11-04 09:57:55 +0000
committerMaxim Kuvyrkov <mkuvyrkov@gcc.gnu.org>2009-11-04 09:57:55 +0000
commitdb5e2d51eb566289a529cc530f037c76483ce61c (patch)
tree56013311796c3566afd1753de263d08fde422081 /gcc
parente3b8749b11ce6763e1b413958b15955095ffd099 (diff)
downloadgcc-db5e2d51eb566289a529cc530f037c76483ce61c.zip
gcc-db5e2d51eb566289a529cc530f037c76483ce61c.tar.gz
gcc-db5e2d51eb566289a529cc530f037c76483ce61c.tar.bz2
[multiple changes]
2009-11-04 Maxim Kuvyrkov <maxim@codesourcery.com> PR target/41302 * config/m68k/m68k.c (m68k_reg_present_p): New static function. (m68k_ok_for_sibcall_p): Handle different result return locations. 2009-11-04 Carlos O'Donell <carlos@codesourcery.com> PR target/41302 * gcc.target/m68k/pr41302.c: New test. From-SVN: r153890
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/m68k/m68k.c47
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/m68k/pr41302.c14
4 files changed, 72 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 00d9025..e4bfa40 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2009-11-04 Maxim Kuvyrkov <maxim@codesourcery.com>
+
+ PR target/41302
+ * config/m68k/m68k.c (m68k_reg_present_p): New static function.
+ (m68k_ok_for_sibcall_p): Handle different result return locations.
+
2009-11-04 Richard Guenther <rguenther@suse.de>
* c-opts.c (c_common_post_options): Move LTO option processing
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 0862936..8db98fc 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -1399,6 +1399,30 @@ flags_in_68881 (void)
return cc_status.flags & CC_IN_68881;
}
+/* Return true if PARALLEL contains register REGNO. */
+static bool
+m68k_reg_present_p (const_rtx parallel, unsigned int regno)
+{
+ int i;
+
+ if (REG_P (parallel) && REGNO (parallel) == regno)
+ return true;
+
+ if (GET_CODE (parallel) != PARALLEL)
+ return false;
+
+ for (i = 0; i < XVECLEN (parallel, 0); ++i)
+ {
+ const_rtx x;
+
+ x = XEXP (XVECEXP (parallel, 0, i), 0);
+ if (REG_P (x) && REGNO (x) == regno)
+ return true;
+ }
+
+ return false;
+}
+
/* Implement TARGET_FUNCTION_OK_FOR_SIBCALL_P. */
static bool
@@ -1411,6 +1435,26 @@ m68k_ok_for_sibcall_p (tree decl, tree exp)
if (CALL_EXPR_STATIC_CHAIN (exp))
return false;
+ if (!VOID_TYPE_P (TREE_TYPE (DECL_RESULT (cfun->decl))))
+ {
+ /* Check that the return value locations are the same. For
+ example that we aren't returning a value from the sibling in
+ a D0 register but then need to transfer it to a A0 register. */
+ rtx cfun_value;
+ rtx call_value;
+
+ cfun_value = FUNCTION_VALUE (TREE_TYPE (DECL_RESULT (cfun->decl)),
+ cfun->decl);
+ call_value = FUNCTION_VALUE (TREE_TYPE (exp), decl);
+
+ /* Check that the values are equal or that the result the callee
+ function returns is superset of what the current function returns. */
+ if (!(rtx_equal_p (cfun_value, call_value)
+ || (REG_P (cfun_value)
+ && m68k_reg_present_p (call_value, REGNO (cfun_value)))))
+ return false;
+ }
+
kind = m68k_get_function_kind (current_function_decl);
if (kind == m68k_fk_normal_function)
/* We can always sibcall from a normal function, because it's
@@ -5188,6 +5232,9 @@ m68k_libcall_value (enum machine_mode mode)
return gen_rtx_REG (mode, m68k_libcall_value_in_a0_p ? A0_REG : D0_REG);
}
+/* Location in which function value is returned.
+ NOTE: Due to differences in ABIs, don't call this function directly,
+ use FUNCTION_VALUE instead. */
rtx
m68k_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f525db0..0187c43 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-11-04 Carlos O'Donell <carlos@codesourcery.com>
+
+ PR target/41302
+ * gcc.target/m68k/pr41302.c: New test.
+
2009-11-03 Jason Merrill <jason@redhat.com>
PR c++/36959
diff --git a/gcc/testsuite/gcc.target/m68k/pr41302.c b/gcc/testsuite/gcc.target/m68k/pr41302.c
new file mode 100644
index 0000000..8e1c310
--- /dev/null
+++ b/gcc/testsuite/gcc.target/m68k/pr41302.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler "move.l \%d0,\%a0" { target *linux* } } } */
+
+struct pts {
+ int c;
+};
+
+unsigned int bar (struct pts *a, int b);
+
+struct pts * foo (struct pts *a, int b)
+{
+ return (struct pts *) bar (a, b);
+}