OSDN Git Service

* calls.c (store_arg): Return non-zero if sibcall_failure is
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 Jul 2000 08:54:33 +0000 (08:54 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 18 Jul 2000 08:54:33 +0000 (08:54 +0000)
desired.
(expand_call): Adjust caller.
* gcc.c-torture/execute/20000717-5.c: New test.
* gcc.c-torture/execute/20000717-1.x: Removed.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@35117 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/calls.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20000717-1.x [deleted file]
gcc/testsuite/gcc.c-torture/execute/20000717-5.c [new file with mode: 0644]

index 7260401..b183280 100644 (file)
@@ -1,3 +1,9 @@
+2000-07-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * calls.c (store_arg): Return non-zero if sibcall_failure is
+       desired.
+       (expand_call): Adjust caller.
+
 2000-07-17  Gabriel Dos Reis  <gdr@codesourcery.com>
 
         * diagnostic.h (report_diagnostic): Change prototype.
@@ -14,7 +20,7 @@
         * c-errors.c (pedwarn_c99): Adjust call to report_diagnostic. End
         varaible argument list.
        
-2000-02-17  Zack Weinberg  <zack@wolery.cumb.org>
+2000-07-17  Zack Weinberg  <zack@wolery.cumb.org>
 
        * cpphash.c: Don't include hashtab.h.  Most macro-handling code
        moved to cppmacro.c.
@@ -41,7 +47,7 @@
 
        * cppmain.c: Do not set pfile->printer if no_output is on.
 
-2000-02-15  Neil Booth  <neilb@earthling.net>
+2000-07-15  Neil Booth  <neilb@earthling.net>
 
        * cpplib.c: Change all directive-handler functions to return
        void, not int.
index 784b3b1..8c5b9bc 100644 (file)
@@ -191,7 +191,7 @@ static void emit_call_1             PARAMS ((rtx, tree, tree, HOST_WIDE_INT,
 static void precompute_register_parameters     PARAMS ((int,
                                                         struct arg_data *,
                                                         int *));
-static void store_one_arg      PARAMS ((struct arg_data *, rtx, int, int,
+static int store_one_arg       PARAMS ((struct arg_data *, rtx, int, int,
                                         int));
 static void store_unaligned_arguments_into_pseudos PARAMS ((struct arg_data *,
                                                            int));
@@ -1952,10 +1952,10 @@ check_sibcall_argument_overlap_1 (x)
     {
       if (XEXP (x, 0) == current_function_internal_arg_pointer)
        i = 0;
-      else if (GET_CODE (XEXP (x, 0)) == PLUS &&
-              XEXP (XEXP (x, 0), 0) ==
-                current_function_internal_arg_pointer &&
-              GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
+      else if (GET_CODE (XEXP (x, 0)) == PLUS
+              && XEXP (XEXP (x, 0), 0) ==
+                 current_function_internal_arg_pointer
+              && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
        i = INTVAL (XEXP (XEXP (x, 0), 1));
       else
        return 0;
@@ -2947,10 +2947,12 @@ expand_call (exp, target, ignore)
          {
            rtx before_arg = get_last_insn ();
 
-           store_one_arg (&args[i], argblock, flags,
-                          adjusted_args_size.var != 0, reg_parm_stack_space);
-           if (pass == 0 &&
-               check_sibcall_argument_overlap (before_arg, &args[i]))
+           if (store_one_arg (&args[i], argblock, flags,
+                              adjusted_args_size.var != 0,
+                              reg_parm_stack_space)
+               || (pass == 0
+                   && check_sibcall_argument_overlap (before_arg,
+                                                      &args[i])))
              sibcall_failure = 1;
          }
 
@@ -2969,10 +2971,12 @@ expand_call (exp, target, ignore)
            {
              rtx before_arg = get_last_insn ();
 
-             store_one_arg (&args[i], argblock, flags,
-                            adjusted_args_size.var != 0, reg_parm_stack_space);
-             if (pass == 0 &&
-                 check_sibcall_argument_overlap (before_arg, &args[i]))
+             if (store_one_arg (&args[i], argblock, flags,
+                                adjusted_args_size.var != 0,
+                                reg_parm_stack_space)
+                 || (pass == 0
+                     && check_sibcall_argument_overlap (before_arg,
+                                                        &args[i])))
                sibcall_failure = 1;
            }
 
@@ -4218,9 +4222,12 @@ target_for_arg (type, size, args_addr, offset)
    argument stack.  This is used if ACCUMULATE_OUTGOING_ARGS to indicate
    that we need not worry about saving and restoring the stack.
 
-   FNDECL is the declaration of the function we are calling.  */
+   FNDECL is the declaration of the function we are calling.
+   
+   Return non-zero if this arg should cause sibcall failure,
+   zero otherwise.  */
 
-static void
+static int
 store_one_arg (arg, argblock, flags, variable_size,
               reg_parm_stack_space)
      struct arg_data *arg;
@@ -4234,9 +4241,10 @@ store_one_arg (arg, argblock, flags, variable_size,
   int partial = 0;
   int used = 0;
   int i, lower_bound = 0, upper_bound = 0;
+  int sibcall_failure = 0;
 
   if (TREE_CODE (pval) == ERROR_MARK)
-    return;
+    return 1;
 
   /* Push a new temporary level for any temporaries we make for
      this argument.  */
@@ -4451,6 +4459,39 @@ store_one_arg (arg, argblock, flags, variable_size,
          size_rtx = expr_size (pval);
        }
 
+      if ((flags & ECF_SIBCALL) && GET_CODE (arg->value) == MEM)
+       {
+         /* emit_push_insn might not work properly if arg->value and
+            argblock + arg->offset areas overlap.  */
+         rtx x = arg->value;
+         int i = 0;
+
+         if (XEXP (x, 0) == current_function_internal_arg_pointer
+             || (GET_CODE (XEXP (x, 0)) == PLUS
+                 && XEXP (XEXP (x, 0), 0) ==
+                    current_function_internal_arg_pointer
+                 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT))
+           {
+             if (XEXP (x, 0) != current_function_internal_arg_pointer)
+               i = INTVAL (XEXP (XEXP (x, 0), 1));
+
+             /* expand_call should ensure this */
+             if (arg->offset.var || GET_CODE (size_rtx) != CONST_INT)
+               abort ();
+
+             if (arg->offset.constant > i)
+               {
+                 if (arg->offset.constant < i + INTVAL (size_rtx))
+                   sibcall_failure = 1;
+               }
+             else if (arg->offset.constant < i)
+               {
+                 if (i < arg->offset.constant + INTVAL (size_rtx))
+                   sibcall_failure = 1;
+               }
+           }
+       }
+
       emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
                      TYPE_ALIGN (TREE_TYPE (pval)), partial, reg, excess,
                      argblock, ARGS_SIZE_RTX (arg->offset),
@@ -4482,4 +4523,6 @@ store_one_arg (arg, argblock, flags, variable_size,
   preserve_temp_slots (NULL_RTX);
   free_temp_slots ();
   pop_temp_slots ();
+
+  return sibcall_failure;
 }
index 95d657f..42c8a64 100644 (file)
@@ -1,3 +1,8 @@
+2000-07-18  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.c-torture/execute/20000717-5.c: New test.
+       * gcc.c-torture/execute/20000717-1.x: Removed.
+
 2000-07-17  Richard Henderson  <rth@cygnus.com>
 
        * gcc.c-torture/execute/20000717-4.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20000717-1.x b/gcc/testsuite/gcc.c-torture/execute/20000717-1.x
deleted file mode 100644 (file)
index 1005ae6..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-set torture_execute_xfail "*-*-*"
-
-return 0
diff --git a/gcc/testsuite/gcc.c-torture/execute/20000717-5.c b/gcc/testsuite/gcc.c-torture/execute/20000717-5.c
new file mode 100644 (file)
index 0000000..49dcbbc
--- /dev/null
@@ -0,0 +1,23 @@
+typedef struct trio { int a, b, c; } trio;
+
+int
+bar (int i, int j, int k, trio t)
+{
+  if (t.a != 1 || t.b != 2 || t.c != 3 ||
+      i != 4 || j != 5 || k != 6)
+    abort ();
+}
+
+int
+foo (trio t, int i, int j, int k)
+{
+  return bar (i, j, k, t);
+}
+
+main ()
+{
+  trio t = { 1, 2, 3 };
+
+  foo (t, 4, 5, 6);
+  exit (0);
+}