OSDN Git Service

* cp-tree.h (build_lang_field_decl): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / calls.c
index 185b0e1..b646be8 100644 (file)
@@ -24,6 +24,7 @@ Boston, MA 02111-1307, USA.  */
 #include "tree.h"
 #include "flags.h"
 #include "expr.h"
+#include "function.h"
 #include "regs.h"
 #include "insn-flags.h"
 #include "toplev.h"
@@ -127,8 +128,8 @@ int stack_arg_under_construction;
 static int calls_function      PROTO ((tree, int));
 static int calls_function_1    PROTO ((tree, int));
 static void emit_call_1                PROTO ((rtx, tree, tree, HOST_WIDE_INT,
-                                       HOST_WIDE_INT, rtx, rtx,
-                                       int, rtx, int));
+                                       HOST_WIDE_INT, HOST_WIDE_INT, rtx,
+                                       rtx, int, rtx, int));
 static void special_function_p PROTO ((char *, tree, int *, int *,
                                        int *, int *));
 static void precompute_register_parameters     PROTO ((int, struct arg_data *,
@@ -218,8 +219,7 @@ calls_function_1 (exp, which)
          if ((DECL_BUILT_IN (fndecl)
               && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_ALLOCA)
              || (DECL_SAVED_INSNS (fndecl)
-                 && (FUNCTION_FLAGS (DECL_SAVED_INSNS (fndecl))
-                     & FUNCTION_FLAGS_CALLS_ALLOCA)))
+                 && DECL_SAVED_INSNS (fndecl)->calls_alloca))
            return 1;
        }
 
@@ -374,13 +374,14 @@ prepare_call_address (funexp, fndecl, call_fusage, reg_parm_seen)
    IS_CONST is true if this is a `const' call.  */
 
 static void
-emit_call_1 (funexp, fndecl, funtype, stack_size, struct_value_size, 
-             next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
-            is_const)
+emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
+            struct_value_size, next_arg_reg, valreg, old_inhibit_defer_pop,
+            call_fusage, is_const)
      rtx funexp;
      tree fndecl ATTRIBUTE_UNUSED;
      tree funtype ATTRIBUTE_UNUSED;
      HOST_WIDE_INT stack_size;
+     HOST_WIDE_INT rounded_stack_size;
      HOST_WIDE_INT struct_value_size;
      rtx next_arg_reg;
      rtx valreg;
@@ -388,11 +389,12 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, struct_value_size,
      rtx call_fusage;
      int is_const;
 {
-  rtx stack_size_rtx = GEN_INT (stack_size);
+  rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
   rtx struct_value_size_rtx = GEN_INT (struct_value_size);
   rtx call_insn;
 #ifndef ACCUMULATE_OUTGOING_ARGS
   int already_popped = 0;
+  HOST_WIDE_INT n_popped = RETURN_POPS_ARGS (fndecl, funtype, stack_size);
 #endif
 
   /* Ensure address is valid.  SYMBOL_REF is already valid, so no need,
@@ -403,11 +405,9 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, struct_value_size,
 
 #ifndef ACCUMULATE_OUTGOING_ARGS
 #if defined (HAVE_call_pop) && defined (HAVE_call_value_pop)
-  if (HAVE_call_pop && HAVE_call_value_pop
-      && (RETURN_POPS_ARGS (fndecl, funtype, stack_size) > 0 
-          || stack_size == 0))
+  if (HAVE_call_pop && HAVE_call_value_pop && n_popped > 0)
     {
-      rtx n_pop = GEN_INT (RETURN_POPS_ARGS (fndecl, funtype, stack_size));
+      rtx n_pop = GEN_INT (n_popped);
       rtx pat;
 
       /* If this subroutine pops its own args, record that in the call insn
@@ -416,10 +416,10 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, struct_value_size,
       if (valreg)
        pat = gen_call_value_pop (valreg,
                                  gen_rtx_MEM (FUNCTION_MODE, funexp),
-                                 stack_size_rtx, next_arg_reg, n_pop);
+                                 rounded_stack_size_rtx, next_arg_reg, n_pop);
       else
        pat = gen_call_pop (gen_rtx_MEM (FUNCTION_MODE, funexp),
-                           stack_size_rtx, next_arg_reg, n_pop);
+                           rounded_stack_size_rtx, next_arg_reg, n_pop);
 
       emit_call_insn (pat);
       already_popped = 1;
@@ -434,11 +434,11 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, struct_value_size,
       if (valreg)
        emit_call_insn (gen_call_value (valreg,
                                        gen_rtx_MEM (FUNCTION_MODE, funexp),
-                                       stack_size_rtx, next_arg_reg,
+                                       rounded_stack_size_rtx, next_arg_reg,
                                        NULL_RTX));
       else
        emit_call_insn (gen_call (gen_rtx_MEM (FUNCTION_MODE, funexp),
-                                 stack_size_rtx, next_arg_reg,
+                                 rounded_stack_size_rtx, next_arg_reg,
                                  struct_value_size_rtx));
     }
   else
@@ -485,23 +485,23 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, struct_value_size,
      If returning from the subroutine does pop the args, indicate that the
      stack pointer will be changed.  */
 
-  if (stack_size != 0 && RETURN_POPS_ARGS (fndecl, funtype, stack_size) > 0)
+  if (n_popped > 0)
     {
       if (!already_popped)
        CALL_INSN_FUNCTION_USAGE (call_insn)
          = gen_rtx_EXPR_LIST (VOIDmode,
                               gen_rtx_CLOBBER (VOIDmode, stack_pointer_rtx),
                               CALL_INSN_FUNCTION_USAGE (call_insn));
-      stack_size -= RETURN_POPS_ARGS (fndecl, funtype, stack_size);
-      stack_size_rtx = GEN_INT (stack_size);
+      rounded_stack_size -= n_popped;
+      rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
     }
 
-  if (stack_size != 0)
+  if (rounded_stack_size != 0)
     {
       if (flag_defer_pop && inhibit_defer_pop == 0 && !is_const)
-       pending_stack_adjust += stack_size;
+       pending_stack_adjust += rounded_stack_size;
       else
-       adjust_stack (stack_size_rtx);
+       adjust_stack (rounded_stack_size_rtx);
     }
 #endif
 }
@@ -868,10 +868,10 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
                                 actparms, fndecl, args_so_far,
                                 reg_parm_stack_space, old_stack_level,
                                 old_pending_adj, must_preallocate, is_const)
-     int num_actuals;
+     int num_actuals ATTRIBUTE_UNUSED;
      struct arg_data *args;
      struct args_size *args_size;
-     int n_named_args;
+     int n_named_args ATTRIBUTE_UNUSED;
      tree actparms;
      tree fndecl;
      CUMULATIVE_ARGS *args_so_far;
@@ -1168,8 +1168,11 @@ compute_argument_block_size (reg_parm_stack_space, args_size)
   else
     {
 #ifdef PREFERRED_STACK_BOUNDARY
-      args_size->constant = (((args_size->constant + (STACK_BYTES - 1))
-                             / STACK_BYTES) * STACK_BYTES);
+      args_size->constant = (((args_size->constant
+                              + pending_stack_adjust
+                              + STACK_BYTES - 1)
+                             / STACK_BYTES * STACK_BYTES)
+                            - pending_stack_adjust);
 #endif
 
       args_size->constant = MAX (args_size->constant,
@@ -1404,15 +1407,25 @@ rtx_for_function_call (fndecl, exp)
   else
     /* Generate an rtx (probably a pseudo-register) for the address.  */
     {
+      rtx funaddr;
       push_temp_slots ();
-      funexp = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
+      funaddr = funexp = 
+         expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
       pop_temp_slots ();       /* FUNEXP can't be BLKmode */
 
       /* Check the function is executable.  */
       if (current_function_check_memory_usage)
-       emit_library_call (chkr_check_exec_libfunc, 1,
-                          VOIDmode, 1,
-                          funexp, ptr_mode);
+       {
+#ifdef POINTERS_EXTEND_UNSIGNED
+         /* It might be OK to convert funexp in place, but there's
+            a lot going on between here and when it happens naturally
+            that this seems safer. */
+          funaddr = convert_memory_address (Pmode, funexp);
+#endif
+         emit_library_call (chkr_check_exec_libfunc, 1,
+                            VOIDmode, 1,
+                            funaddr, Pmode);
+       }
       emit_queue ();
     }
   return funexp;
@@ -1636,7 +1649,7 @@ expand_call (exp, target, ignore)
              && fndecl != current_function_decl
              && DECL_INLINE (fndecl)
              && DECL_SAVED_INSNS (fndecl)
-             && RTX_INTEGRATED_P (DECL_SAVED_INSNS (fndecl)))
+             && DECL_SAVED_INSNS (fndecl)->inlinable)
            is_integrable = 1;
          else if (! TREE_ADDRESSABLE (fndecl))
            {
@@ -1773,11 +1786,11 @@ expand_call (exp, target, ignore)
              rtx insn, seq;
 
              /* Look for a call in the inline function code.
-                If OUTGOING_ARGS_SIZE (DECL_SAVED_INSNS (fndecl)) is
+                If DECL_SAVED_INSNS (fndecl)->outgoing_args_size is
                 nonzero then there is a call and it is not necessary
                 to scan the insns.  */
 
-             if (OUTGOING_ARGS_SIZE (DECL_SAVED_INSNS (fndecl)) == 0)
+             if (DECL_SAVED_INSNS (fndecl)->outgoing_args_size == 0)
                for (insn = first_insn; insn; insn = NEXT_INSN (insn))
                  if (GET_CODE (insn) == CALL_INSN)
                    break;
@@ -1801,7 +1814,7 @@ expand_call (exp, target, ignore)
                     value of reg_parm_stack_space is wrong, but gives
                     correct results on all supported machines.  */
 
-                 int adjust = (OUTGOING_ARGS_SIZE (DECL_SAVED_INSNS (fndecl))
+                 int adjust = (DECL_SAVED_INSNS (fndecl)->outgoing_args_size
                                + reg_parm_stack_space);
 
                  start_sequence ();
@@ -2253,7 +2266,7 @@ expand_call (exp, target, ignore)
       if (current_function_check_memory_usage)
        emit_library_call (chkr_set_right_libfunc, 1,
                           VOIDmode, 3,
-                          structure_value_addr, ptr_mode, 
+                          structure_value_addr, Pmode, 
                           GEN_INT (struct_value_size), TYPE_MODE (sizetype),
                           GEN_INT (MEMORY_USE_WO),
                           TYPE_MODE (integer_type_node));
@@ -2272,7 +2285,8 @@ expand_call (exp, target, ignore)
   /* All arguments and registers used for the call must be set up by now!  */
 
   /* Generate the actual call instruction.  */
-  emit_call_1 (funexp, fndecl, funtype, args_size.constant, struct_value_size,
+  emit_call_1 (funexp, fndecl, funtype, unadjusted_args_size,
+              args_size.constant, struct_value_size,
               FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
               valreg, old_inhibit_defer_pop, call_fusage, is_const);
 
@@ -2957,7 +2971,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode,
                get_identifier (XSTR (orgfun, 0)), 
               build_function_type (outmode == VOIDmode ? void_type_node
                                    : type_for_mode (outmode, 0), NULL_TREE),
-               args_size.constant, 0,
+              original_args_size.constant, args_size.constant, 0,
               FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
               outmode != VOIDmode ? hard_libcall_value (outmode) : NULL_RTX,
               old_inhibit_defer_pop + 1, call_fusage, no_queue);
@@ -3530,7 +3544,8 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue,
   emit_call_1 (fun, 
                get_identifier (XSTR (orgfun, 0)),
               build_function_type (type_for_mode (outmode, 0), NULL_TREE),
-               args_size.constant, struct_value_size,
+               original_args_size.constant, args_size.constant,
+              struct_value_size,
               FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
               mem_value == 0 ? hard_libcall_value (outmode) : NULL_RTX,
               old_inhibit_defer_pop + 1, call_fusage, is_const);
@@ -3821,7 +3836,7 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
       if (current_function_check_memory_usage && GET_CODE (arg->stack) == MEM)
        {
          emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
-                            XEXP (arg->stack, 0), ptr_mode, 
+                            XEXP (arg->stack, 0), Pmode, 
                             ARGS_SIZE_RTX (arg->size),
                             TYPE_MODE (sizetype),
                             GEN_INT (MEMORY_USE_RW),