OSDN Git Service

* target-def.h (TARGET_MUST_PASS_IN_STACK): New.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Jul 2004 07:45:09 +0000 (07:45 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Jul 2004 07:45:09 +0000 (07:45 +0000)
* target.h (struct gcc_target): Add calls.must_pass_in_stack.
* expr.h (MUST_PASS_IN_STACK): Remove.
* system.h (MUST_PASS_IN_STACK): Poison.
* tree.h (must_pass_in_stack_var_size): Declare.
(must_pass_in_stack_var_size_or_pad): Declare.
* calls.c (must_pass_in_stack_var_size): New.
(must_pass_in_stack_var_size_or_pad): Rename from
default_must_pass_in_stack.
* config/alpha/alpha.c (unicosmk_must_pass_in_stack): New.
(TARGET_MUST_PASS_IN_STACK): New.
* config/alpha/unicosmk.h (MUST_PASS_IN_STACK): Remove.
* config/fr30/fr30.c (fr30_must_pass_in_stack): New.
(TARGET_MUST_PASS_IN_STACK): New.
* config/fr30/fr30.h (MUST_PASS_IN_STACK): Remove.
* config/frv/frv.c (frv_must_pass_in_stack): New.
(TARGET_MUST_PASS_IN_STACK): New.
* config/frv/frv.h (MUST_PASS_IN_STACK): Remove.
* config/i386/i386-protos.h (ix86_must_pass_in_stack): Remove.
* config/i386/i386.c (TARGET_MUST_PASS_IN_STACK): New.
(ix86_must_pass_in_stack): Make static.
* config/i386/i386.h (MUST_PASS_IN_STACK): Remove.
* config/ia64/ia64.c (TARGET_MUST_PASS_IN_STACK): New.
* config/ia64/ia64.h (MUST_PASS_IN_STACK): Remove.
* config/m32r/m32r.c (TARGET_MUST_PASS_IN_STACK): New.
* config/m32r/m32r.h (MUST_PASS_IN_STACK): Remove.
* config/mcore/mcore-protos.h (mcore_must_pass_on_stack): Remove.
* config/mcore/mcore.c (TARGET_MUST_PASS_IN_STACK): New.
(mcore_must_pass_on_stack): Remove.
* config/mcore/mcore.h (MUST_PASS_IN_STACK): Remove.
* config/mips/mips.c (TARGET_MUST_PASS_IN_STACK): New.
* config/mips/mips.h (MUST_PASS_IN_STACK): Remove.
* config/pa/pa.c (TARGET_MUST_PASS_IN_STACK): New.
* config/pa/pa.h (MUST_PASS_IN_STACK): Remove.
* config/rs6000/aix.h (MUST_PASS_IN_STACK): Remove.
* config/rs6000/linux64.h (MUST_PASS_IN_STACK): Remove.
* config/rs6000/rs6000.c (rs6000_must_pass_in_stack): New.
(TARGET_MUST_PASS_IN_STACK): New.
* config/sh/sh.c (TARGET_MUST_PASS_IN_STACK): New.
* config/sh/sh.h (MUST_PASS_IN_STACK): Remove.
* config/sparc/sparc.c (TARGET_MUST_PASS_IN_STACK): New.
* config/sparc/sparc.h (MUST_PASS_IN_STACK): Remove.
* config/xtensa/xtensa.c (TARGET_MUST_PASS_IN_STACK): New.
* config/xtensa/xtensa.h (MUST_PASS_IN_STACK): Remove.
* doc/tm.texi (TARGET_MUST_PASS_IN_STACK): Update from
MUST_PASS_IN_STACK.

* calls.c, function.c, config/alpha/alpha.c, config/alpha/alpha.h,
config/alpha/unicosmk.h, config/alpha/vms.h, config/c4x/c4x.c,
config/cris/cris.h, config/fr30/fr30.c, config/fr30/fr30.h,
config/frv/frv.c, config/i386/i386.c, config/iq2000/iq2000.c,
config/mcore/mcore.c, config/mcore/mcore.h, config/mips/mips.c,
config/mmix/mmix.c, config/mmix/mmix.h, config/rs6000/rs6000.c,
config/sh/sh.c, config/sh/sh.h, config/stormy16/stormy16.c,
config/xtensa/xtensa.c: Use target hook.

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

46 files changed:
gcc/ChangeLog
gcc/calls.c
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/alpha/unicosmk.h
gcc/config/alpha/vms.h
gcc/config/c4x/c4x.c
gcc/config/cris/cris.h
gcc/config/fr30/fr30.c
gcc/config/fr30/fr30.h
gcc/config/frv/frv.c
gcc/config/frv/frv.h
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.h
gcc/config/iq2000/iq2000.c
gcc/config/m32r/m32r.c
gcc/config/m32r/m32r.h
gcc/config/mcore/mcore-protos.h
gcc/config/mcore/mcore.c
gcc/config/mcore/mcore.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mmix/mmix.c
gcc/config/mmix/mmix.h
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/rs6000/aix.h
gcc/config/rs6000/linux64.h
gcc/config/rs6000/rs6000.c
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/config/stormy16/stormy16.c
gcc/config/xtensa/xtensa.c
gcc/config/xtensa/xtensa.h
gcc/doc/tm.texi
gcc/expr.h
gcc/function.c
gcc/system.h
gcc/target-def.h
gcc/target.h
gcc/tree.h

index 8372af0..6c2ef13 100644 (file)
@@ -1,3 +1,61 @@
+2004-07-13  Richard Henderson  <rth@redhat.com>
+
+       * target-def.h (TARGET_MUST_PASS_IN_STACK): New.
+       * target.h (struct gcc_target): Add calls.must_pass_in_stack.
+       * expr.h (MUST_PASS_IN_STACK): Remove.
+       * system.h (MUST_PASS_IN_STACK): Poison.
+       * tree.h (must_pass_in_stack_var_size): Declare.
+       (must_pass_in_stack_var_size_or_pad): Declare.
+       * calls.c (must_pass_in_stack_var_size): New.
+       (must_pass_in_stack_var_size_or_pad): Rename from 
+       default_must_pass_in_stack.
+       * config/alpha/alpha.c (unicosmk_must_pass_in_stack): New.
+       (TARGET_MUST_PASS_IN_STACK): New.
+       * config/alpha/unicosmk.h (MUST_PASS_IN_STACK): Remove.
+       * config/fr30/fr30.c (fr30_must_pass_in_stack): New.
+       (TARGET_MUST_PASS_IN_STACK): New.
+       * config/fr30/fr30.h (MUST_PASS_IN_STACK): Remove.
+       * config/frv/frv.c (frv_must_pass_in_stack): New.
+       (TARGET_MUST_PASS_IN_STACK): New.
+       * config/frv/frv.h (MUST_PASS_IN_STACK): Remove.
+       * config/i386/i386-protos.h (ix86_must_pass_in_stack): Remove.
+       * config/i386/i386.c (TARGET_MUST_PASS_IN_STACK): New.
+       (ix86_must_pass_in_stack): Make static.
+       * config/i386/i386.h (MUST_PASS_IN_STACK): Remove.
+       * config/ia64/ia64.c (TARGET_MUST_PASS_IN_STACK): New.
+       * config/ia64/ia64.h (MUST_PASS_IN_STACK): Remove.
+       * config/m32r/m32r.c (TARGET_MUST_PASS_IN_STACK): New.
+       * config/m32r/m32r.h (MUST_PASS_IN_STACK): Remove.
+       * config/mcore/mcore-protos.h (mcore_must_pass_on_stack): Remove.
+       * config/mcore/mcore.c (TARGET_MUST_PASS_IN_STACK): New.
+       (mcore_must_pass_on_stack): Remove.
+       * config/mcore/mcore.h (MUST_PASS_IN_STACK): Remove.
+       * config/mips/mips.c (TARGET_MUST_PASS_IN_STACK): New.
+       * config/mips/mips.h (MUST_PASS_IN_STACK): Remove.
+       * config/pa/pa.c (TARGET_MUST_PASS_IN_STACK): New.
+       * config/pa/pa.h (MUST_PASS_IN_STACK): Remove.
+       * config/rs6000/aix.h (MUST_PASS_IN_STACK): Remove.
+       * config/rs6000/linux64.h (MUST_PASS_IN_STACK): Remove.
+       * config/rs6000/rs6000.c (rs6000_must_pass_in_stack): New.
+       (TARGET_MUST_PASS_IN_STACK): New.
+       * config/sh/sh.c (TARGET_MUST_PASS_IN_STACK): New.
+       * config/sh/sh.h (MUST_PASS_IN_STACK): Remove.
+       * config/sparc/sparc.c (TARGET_MUST_PASS_IN_STACK): New.
+       * config/sparc/sparc.h (MUST_PASS_IN_STACK): Remove.
+       * config/xtensa/xtensa.c (TARGET_MUST_PASS_IN_STACK): New.
+       * config/xtensa/xtensa.h (MUST_PASS_IN_STACK): Remove.
+       * doc/tm.texi (TARGET_MUST_PASS_IN_STACK): Update from
+       MUST_PASS_IN_STACK.
+
+       * calls.c, function.c, config/alpha/alpha.c, config/alpha/alpha.h,
+       config/alpha/unicosmk.h, config/alpha/vms.h, config/c4x/c4x.c,
+       config/cris/cris.h, config/fr30/fr30.c, config/fr30/fr30.h,
+       config/frv/frv.c, config/i386/i386.c, config/iq2000/iq2000.c,
+       config/mcore/mcore.c, config/mcore/mcore.h, config/mips/mips.c,
+       config/mmix/mmix.c, config/mmix/mmix.h, config/rs6000/rs6000.c,
+       config/sh/sh.c, config/sh/sh.h, config/stormy16/stormy16.c,
+       config/xtensa/xtensa.c: Use target hook.
+
 2004-07-13  Anthony Heading  <aheading@jpmorgan.com>
 
        * configure.ac (gcc_cv_as_offsetable_lo10: Fix a typo.
index c54ab48..e128162 100644 (file)
@@ -1097,7 +1097,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
          = FUNCTION_ARG_PARTIAL_NREGS (*args_so_far, mode, type,
                                        argpos < n_named_args);
 
-      args[i].pass_on_stack = MUST_PASS_IN_STACK (mode, type);
+      args[i].pass_on_stack = targetm.calls.must_pass_in_stack (mode, type);
 
       /* If FUNCTION_ARG returned a (parallel [(expr_list (nil) ...) ...]),
         it means that we are to pass this arg in the register(s) designated
@@ -4445,24 +4445,33 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
   return sibcall_failure;
 }
 
-/* Nonzero if we do not know how to pass TYPE solely in registers.
-   We cannot do so in the following cases:
+/* Nonzero if we do not know how to pass TYPE solely in registers.  */
 
-   - if the type has variable size
-   - if the type is marked as addressable (it is required to be constructed
-     into the stack)
-   - if the padding and mode of the type is such that a copy into a register
-     would put it into the wrong part of the register.
+bool
+must_pass_in_stack_var_size (enum machine_mode mode ATTRIBUTE_UNUSED,
+                            tree type)
+{
+  if (!type)
+    return false;
+
+  /* If the type has variable size...  */
+  if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+    return true;
 
-   Which padding can't be supported depends on the byte endianness.
+  /* If the type is marked as addressable (it is required
+     to be constructed into the stack)...  */
+  if (TREE_ADDRESSABLE (type))
+    return true;
+
+  return false;
+}
 
-   A value in a register is implicitly padded at the most significant end.
-   On a big-endian machine, that is the lower end in memory.
-   So a value padded in memory at the upper end can't go in a register.
-   For a little-endian machine, the reverse is true.  */
+/* Another version of the TARGET_MUST_PASS_IN_STACK hook.  This one 
+   takes trailing padding of a structure into account.  */
+/* ??? Should be able to merge these two by examining BLOCK_REG_PADDING.  */
 
 bool
-default_must_pass_in_stack (enum machine_mode mode, tree type)
+must_pass_in_stack_var_size_or_pad (enum machine_mode mode, tree type)
 {
   if (!type)
     return false;
index 19bf341..422d6c6 100644 (file)
@@ -5842,7 +5842,8 @@ function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, tree type,
        return alpha_arg_info_reg_val (cum);
 
       num_args = cum.num_args;
-      if (num_args >= 6 || MUST_PASS_IN_STACK (mode, type))
+      if (num_args >= 6
+         || targetm.calls.must_pass_in_stack (mode, type))
        return NULL_RTX;
     }
 #elif TARGET_ABI_UNICOSMK
@@ -5885,8 +5886,9 @@ function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, tree type,
 
       size = ALPHA_ARG_SIZE (mode, type, named);
       num_args = cum.num_reg_words;
-      if (MUST_PASS_IN_STACK (mode, type)
-         || cum.num_reg_words + size > 6 || cum.force_stack)
+      if (cum.force_stack
+         || cum.num_reg_words + size > 6
+         || targetm.calls.must_pass_in_stack (mode, type))
        return NULL_RTX;
       else if (type && TYPE_MODE (type) == BLKmode)
        {
@@ -5918,7 +5920,7 @@ function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode, tree type,
       /* VOID is passed as a special flag for "last argument".  */
       if (type == void_type_node)
        basereg = 16;
-      else if (MUST_PASS_IN_STACK (mode, type))
+      else if (targetm.calls.must_pass_in_stack (mode, type))
        return NULL_RTX;
       else if (FUNCTION_ARG_PASS_BY_REFERENCE (cum, mode, type, named))
        basereg = 16;
@@ -6232,7 +6234,7 @@ alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, tree *pre_p)
 
   /* If the type could not be passed in registers, skip the block
      reserved for the registers.  */
-  if (MUST_PASS_IN_STACK (TYPE_MODE (type), type))
+  if (targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
     {
       t = fold_convert (TREE_TYPE (offset), build_int_2 (6*8, 0));
       t = build (MODIFY_EXPR, TREE_TYPE (offset), offset,
@@ -9285,6 +9287,24 @@ alpha_use_linkage (rtx linkage ATTRIBUTE_UNUSED,
 \f
 #if TARGET_ABI_UNICOSMK
 
+/* This evaluates to true if we do not know how to pass TYPE solely in
+   registers.  This is the case for all arguments that do not fit in two
+   registers.  */
+
+static bool
+unicosmk_must_pass_in_stack (enum machine_mode mode, tree type)
+{
+  if (type == NULL)
+    return false;
+
+  if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+    return true;
+  if (TREE_ADDRESSABLE (type))
+    return true;
+
+  return ALPHA_ARG_SIZE (mode, type, 0) > 2;
+}
+
 /* Define the offset between two registers, one to be eliminated, and the
    other its replacement, at the start of a routine.  */
 
@@ -10078,6 +10098,8 @@ alpha_init_libfuncs (void)
 # define TARGET_ASM_UNIQUE_SECTION unicosmk_unique_section
 # undef TARGET_ASM_GLOBALIZE_LABEL
 # define TARGET_ASM_GLOBALIZE_LABEL hook_void_FILEptr_constcharptr
+# undef TARGET_MUST_PASS_IN_STACK
+# define TARGET_MUST_PASS_IN_STACK unicosmk_must_pass_in_stack
 #endif
 
 #undef TARGET_ASM_ALIGNED_HI_OP
index 8dbdeb0..e142e5e 100644 (file)
@@ -1040,10 +1040,9 @@ extern int alpha_memory_latency;
    (TYPE is null for libcalls where that information may not be available.)  */
 
 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)                   \
-  if (MUST_PASS_IN_STACK (MODE, TYPE))                                 \
-    (CUM) = 6;                                                         \
-  else                                                                 \
-    (CUM) += ALPHA_ARG_SIZE (MODE, TYPE, NAMED)
+  ((CUM) +=                                                            \
+   (targetm.calls.must_pass_in_stack (MODE, TYPE))                     \
+    ? 6 : ALPHA_ARG_SIZE (MODE, TYPE, NAMED))
 
 /* Determine where to put an argument to a function.
    Value is zero to push the argument on the stack,
index d1dfe91..7c9a607 100644 (file)
@@ -124,15 +124,6 @@ Boston, MA 02111-1307, USA.  */
 
 #define STACK_PARMS_IN_REG_PARM_AREA
 
-/* This evaluates to nonzero if we do not know how to pass TYPE solely in
-   registers. This is the case for all arguments that do not fit in two
-   registers.  */
-
-#define MUST_PASS_IN_STACK(MODE,TYPE)                                  \
-  ((TYPE) != 0                                                         \
-   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST                     \
-       || (TREE_ADDRESSABLE (TYPE) || ALPHA_ARG_SIZE (MODE, TYPE, 0) > 2)))
-
 /* Define a data type for recording info about an argument list
    during the scan of that argument list.  This data type should
    hold all necessary information about the function itself
@@ -198,8 +189,9 @@ do {                                                                \
                                                                \
   size = ALPHA_ARG_SIZE (MODE, TYPE, NAMED);                   \
                                                                 \
-  if (size > 2 || MUST_PASS_IN_STACK (MODE, TYPE)              \
-      || (CUM).num_reg_words + size > 6)                       \
+  if (size > 2                                                 \
+      || (CUM).num_reg_words + size > 6                                \
+      || targetm.calls.must_pass_in_stack (MODE, TYPE))                \
     (CUM).force_stack = 1;                                     \
                                                                 \
   if (! (CUM).force_stack)                                     \
index f7058f3..b062d61 100644 (file)
@@ -179,7 +179,7 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info;
 
 #undef FUNCTION_ARG_ADVANCE
 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)                   \
-  if (MUST_PASS_IN_STACK (MODE, TYPE))                                 \
+  if (targetm.calls.must_pass_in_stack (MODE, TYPE))                   \
     (CUM).num_args += 6;                                               \
   else                                                                 \
     {                                                                  \
index dff0da4..bc384ee 100644 (file)
@@ -575,7 +575,7 @@ c4x_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname)
 
          if ((mode = TYPE_MODE (type)))
            {
-             if (! MUST_PASS_IN_STACK (mode, type))
+             if (! targetm.calls.must_pass_in_stack (mode, type))
                {
                  /* Look for float, double, or long double argument.  */
                  if (mode == QFmode || mode == HFmode)
@@ -612,7 +612,7 @@ c4x_function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
   if (! TARGET_MEMPARM 
       && named
       && type
-      && ! MUST_PASS_IN_STACK (mode, type))
+      && ! targetm.calls.must_pass_in_stack (mode, type))
     {
       /* Look for float, double, or long double argument.  */
       if (mode == QFmode || mode == HFmode)
@@ -678,7 +678,7 @@ c4x_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
   if (! TARGET_MEMPARM 
       && named 
       && type
-      && ! MUST_PASS_IN_STACK (mode, type))
+      && ! targetm.calls.must_pass_in_stack (mode, type))
     {
       /* Look for float, double, or long double argument.  */
       if (mode == QFmode || mode == HFmode)
index 3eabb51..252992b 100644 (file)
@@ -961,7 +961,7 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
 
 #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED)     \
  (((CUM).regs == (CRIS_MAX_ARGS_IN_REGS - 1)                   \
-   && !MUST_PASS_IN_STACK (MODE, TYPE)                         \
+   && !targetm.calls.must_pass_in_stack (MODE, TYPE)           \
    && CRIS_FUNCTION_ARG_SIZE (MODE, TYPE) > 4                  \
    && CRIS_FUNCTION_ARG_SIZE (MODE, TYPE) <= 8)                        \
   ? 1 : 0)
@@ -970,7 +970,7 @@ enum reg_class {NO_REGS, ALL_REGS, LIM_REG_CLASSES};
    bytes long.  If you tweak this, don't forget to adjust
    cris_expand_builtin_va_arg.  */
 #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED)         \
- (MUST_PASS_IN_STACK (MODE, TYPE)                                      \
+ (targetm.calls.must_pass_in_stack (MODE, TYPE)                                \
   || CRIS_FUNCTION_ARG_SIZE (MODE, TYPE) > 8)                          \
 
 /* Contrary to what you'd believe, defining FUNCTION_ARG_CALLEE_COPIES
index d0213d2..017acfd 100644 (file)
@@ -124,6 +124,7 @@ static struct fr30_frame_info       zero_frame_info;
 static void fr30_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
                                         tree, int *, int);
 static tree fr30_gimplify_va_arg_expr (tree, tree, tree *, tree *);
+static bool fr30_must_pass_in_stack (enum machine_mode, tree);
 
 #define FRAME_POINTER_MASK     (1 << (FRAME_POINTER_REGNUM))
 #define RETURN_POINTER_MASK    (1 << (RETURN_POINTER_REGNUM))
@@ -152,9 +153,11 @@ static tree fr30_gimplify_va_arg_expr (tree, tree, tree *, tree *);
 
 #undef  TARGET_PROMOTE_PROTOTYPES
 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
-
 #undef  TARGET_SETUP_INCOMING_VARARGS
 #define TARGET_SETUP_INCOMING_VARARGS fr30_setup_incoming_varargs
+#undef  TARGET_MUST_PASS_IN_STACK
+#define TARGET_MUST_PASS_IN_STACK fr30_must_pass_in_stack
+
 #undef  TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR fr30_gimplify_va_arg_expr
 
@@ -664,6 +667,19 @@ fr30_print_operand (FILE *file, rtx x, int code)
 /*}}}*/
 /*{{{  Function arguments */ 
 
+/* Return true if we should pass an argument on the stack rather than
+   in registers.  */
+
+static bool
+fr30_must_pass_in_stack (enum machine_mode mode, tree type)
+{
+  if (mode == BLKmode)
+    return true;
+  if (type == NULL)
+    return false;
+  return AGGREGATE_TYPE_P (type);
+}
+
 /* Compute the number of word sized registers needed to hold a
    function argument of mode INT_MODE and tree type TYPE.  */
 int
@@ -671,7 +687,7 @@ fr30_num_arg_regs (enum machine_mode mode, tree type)
 {
   int size;
 
-  if (MUST_PASS_IN_STACK (mode, type))
+  if (targetm.calls.must_pass_in_stack (mode, type))
     return 0;
 
   if (type && mode == BLKmode)
index 1260075..b8bec8e 100644 (file)
@@ -651,46 +651,13 @@ enum reg_class
 /*}}}*/ \f
 /*{{{  Function Arguments in Registers.  */ 
 
-/* Nonzero if we do not know how to pass TYPE solely in registers.
-   We cannot do so in the following cases:
-
-   - if the type has variable size
-   - if the type is marked as addressable (it is required to be constructed
-     into the stack)
-   - if the type is a structure or union.  */
-
-#define MUST_PASS_IN_STACK(MODE, TYPE)                         \
-   (((MODE) == BLKmode)                                                \
-    || ((TYPE) != NULL                                         \
-         && TYPE_SIZE (TYPE) != NULL                           \
-         && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST       \
-            || TREE_CODE (TYPE) == RECORD_TYPE                 \
-            || TREE_CODE (TYPE) == UNION_TYPE                  \
-            || TREE_CODE (TYPE) == QUAL_UNION_TYPE             \
-             || TREE_ADDRESSABLE (TYPE))))
-
 /* The number of register assigned to holding function arguments.  */
      
 #define FR30_NUM_ARG_REGS       4
 
-/* A C expression that controls whether a function argument is passed in a
-   register, and which register.
-
-   The usual way to make the ANSI library `stdarg.h' work on a machine where
-   some arguments are usually passed in registers, is to cause nameless
-   arguments to be passed on the stack instead.  This is done by making
-   `FUNCTION_ARG' return 0 whenever NAMED is 0.
-
-   You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
-   this macro to determine if this argument is of a type that must be passed in
-   the stack.  If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
-   returns nonzero for such an argument, the compiler will abort.  If
-   `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
-   stack and then loaded into a register.  */
-     
 #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)                   \
   (  (NAMED) == 0                    ? NULL_RTX                        \
-   : MUST_PASS_IN_STACK (MODE, TYPE) ? NULL_RTX                        \
+   : targetm.calls.must_pass_in_stack (MODE, TYPE) ? NULL_RTX  \
    : (CUM) >= FR30_NUM_ARG_REGS      ? NULL_RTX                        \
    : gen_rtx_REG (MODE, CUM + FIRST_ARG_REGNUM))
 
@@ -727,18 +694,8 @@ enum reg_class
 #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED)     \
   fr30_function_arg_partial_nregs (CUM, MODE, TYPE, NAMED)
 
-/* A C expression that indicates when an argument must be passed by reference.
-   If nonzero for an argument, a copy of that argument is made in memory and a
-   pointer to the argument is passed instead of the argument itself.  The
-   pointer is passed in whatever way is appropriate for passing a pointer to
-   that type.
-
-   On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
-   definition of this macro might be:
-        #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED)  \
-          MUST_PASS_IN_STACK (MODE, TYPE)  */
 #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
-  MUST_PASS_IN_STACK (MODE, TYPE)
+  targetm.calls.must_pass_in_stack (MODE, TYPE)
 
 /* A C statement (sans semicolon) for initializing the variable CUM for the
    state at the beginning of the argument list.  The variable has type
index 9866320..4d05bd4 100644 (file)
@@ -287,6 +287,7 @@ static void frv_output_const_unspec         (FILE *,
 static bool frv_function_ok_for_sibcall                (tree, tree);
 static rtx frv_struct_value_rtx                        (tree, int);
 static tree frv_gimplify_va_arg_expr           (tree, tree, tree *, tree *);
+static bool frv_must_pass_in_stack (enum machine_mode mode, tree type);
 \f
 /* Initialize the GCC target structure.  */
 #undef  TARGET_ASM_FUNCTION_PROLOGUE
@@ -327,6 +328,8 @@ static tree frv_gimplify_va_arg_expr                (tree, tree, tree *, tree *);
 
 #undef TARGET_STRUCT_VALUE_RTX
 #define TARGET_STRUCT_VALUE_RTX frv_struct_value_rtx
+#undef TARGET_MUST_PASS_IN_STACK
+#define TARGET_MUST_PASS_IN_STACK frv_must_pass_in_stack
 
 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
 #define TARGET_EXPAND_BUILTIN_SAVEREGS frv_expand_builtin_saveregs
@@ -3026,6 +3029,19 @@ frv_init_cumulative_args (CUMULATIVE_ARGS *cum,
 }
 
 \f
+/* Return true if we should pass an argument on the stack rather than
+   in registers.  */
+
+static bool
+frv_must_pass_in_stack (enum machine_mode mode, tree type)
+{
+  if (mode == BLKmode)
+    return true;
+  if (type == NULL)
+    return false;
+  return AGGREGATE_TYPE_P (type);
+}
+
 /* If defined, a C expression that gives the alignment boundary, in bits, of an
    argument with the specified mode and type.  If it is not defined,
    `PARM_BOUNDARY' is used for all arguments.  */
@@ -3037,37 +3053,6 @@ frv_function_arg_boundary (enum machine_mode mode ATTRIBUTE_UNUSED,
   return BITS_PER_WORD;
 }
 
-\f
-/* A C expression that controls whether a function argument is passed in a
-   register, and which register.
-
-   The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes (in a way
-   defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE) all of the previous
-   arguments so far passed in registers; MODE, the machine mode of the argument;
-   TYPE, the data type of the argument as a tree node or 0 if that is not known
-   (which happens for C support library functions); and NAMED, which is 1 for an
-   ordinary argument and 0 for nameless arguments that correspond to `...' in the
-   called function's prototype.
-
-   The value of the expression should either be a `reg' RTX for the hard
-   register in which to pass the argument, or zero to pass the argument on the
-   stack.
-
-   For machines like the VAX and 68000, where normally all arguments are
-   pushed, zero suffices as a definition.
-
-   The usual way to make the ANSI library `stdarg.h' work on a machine where
-   some arguments are usually passed in registers, is to cause nameless
-   arguments to be passed on the stack instead.  This is done by making
-   `FUNCTION_ARG' return 0 whenever NAMED is 0.
-
-   You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
-   this macro to determine if this argument is of a type that must be passed in
-   the stack.  If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
-   returns nonzero for such an argument, the compiler will abort.  If
-   `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
-   stack and then loaded into a register.  */
-
 rtx
 frv_function_arg (CUMULATIVE_ARGS *cum,
                   enum machine_mode mode,
@@ -3177,25 +3162,13 @@ frv_function_arg_partial_nregs (CUMULATIVE_ARGS *cum,
 }
 
 \f
-
-/* A C expression that indicates when an argument must be passed by reference.
-   If nonzero for an argument, a copy of that argument is made in memory and a
-   pointer to the argument is passed instead of the argument itself.  The
-   pointer is passed in whatever way is appropriate for passing a pointer to
-   that type.
-
-   On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
-   definition of this macro might be
-        #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED)  \
-          MUST_PASS_IN_STACK (MODE, TYPE)  */
-
 int
 frv_function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
                                     enum machine_mode mode,
                                     tree type,
                                     int named ATTRIBUTE_UNUSED)
 {
-  return MUST_PASS_IN_STACK (mode, type);
+  return targetm.calls.must_pass_in_stack (mode, type);
 }
 
 /* If defined, a C expression that indicates when it is the called function's
index 29d22e4..493ebc7 100644 (file)
@@ -1860,58 +1860,10 @@ struct machine_function GTY(())
 #define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
 
 \f
-/* Function Arguments in Registers.  */
-
-/* Nonzero if we do not know how to pass TYPE solely in registers.
-   We cannot do so in the following cases:
-
-   - if the type has variable size
-   - if the type is marked as addressable (it is required to be constructed
-     into the stack)
-   - if the type is a structure or union.  */
-
-#define MUST_PASS_IN_STACK(MODE,TYPE)                           \
-   (((MODE) == BLKmode)                                         \
-    || ((TYPE) != 0                                             \
-         && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST        \
-             || TREE_CODE (TYPE) == RECORD_TYPE                 \
-             || TREE_CODE (TYPE) == UNION_TYPE                  \
-             || TREE_CODE (TYPE) == QUAL_UNION_TYPE             \
-             || TREE_ADDRESSABLE (TYPE))))
-
 /* The number of register assigned to holding function arguments.  */
 
 #define FRV_NUM_ARG_REGS        6
 
-/* A C expression that controls whether a function argument is passed in a
-   register, and which register.
-
-   The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes (in a way
-   defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE) all of the previous
-   arguments so far passed in registers; MODE, the machine mode of the argument;
-   TYPE, the data type of the argument as a tree node or 0 if that is not known
-   (which happens for C support library functions); and NAMED, which is 1 for an
-   ordinary argument and 0 for nameless arguments that correspond to `...' in the
-   called function's prototype.
-
-   The value of the expression should either be a `reg' RTX for the hard
-   register in which to pass the argument, or zero to pass the argument on the
-   stack.
-
-   For machines like the VAX and 68000, where normally all arguments are
-   pushed, zero suffices as a definition.
-
-   The usual way to make the ANSI library `stdarg.h' work on a machine where
-   some arguments are usually passed in registers, is to cause nameless
-   arguments to be passed on the stack instead.  This is done by making
-   `FUNCTION_ARG' return 0 whenever NAMED is 0.
-
-   You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
-   this macro to determine if this argument is of a type that must be passed in
-   the stack.  If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
-   returns nonzero for such an argument, the compiler will abort.  If
-   `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
-   stack and then loaded into a register.  */
 #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)                    \
   frv_function_arg (&CUM, MODE, TYPE, NAMED, FALSE)
 
@@ -1949,16 +1901,6 @@ struct machine_function GTY(())
 
 /* extern int frv_function_arg_partial_nregs (CUMULATIVE_ARGS, int, Tree, int);  */
 
-/* A C expression that indicates when an argument must be passed by reference.
-   If nonzero for an argument, a copy of that argument is made in memory and a
-   pointer to the argument is passed instead of the argument itself.  The
-   pointer is passed in whatever way is appropriate for passing a pointer to
-   that type.
-
-   On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
-   definition of this macro might be
-        #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED)  \
-          MUST_PASS_IN_STACK (MODE, TYPE)  */
 #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED)         \
   frv_function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED)
 
index 6cf6fe2..7fb122d 100644 (file)
@@ -216,7 +216,6 @@ extern int x86_field_alignment (tree, int);
 #endif
 
 extern rtx ix86_tls_get_addr (void);
-extern bool ix86_must_pass_in_stack (enum machine_mode mode, tree);
 
 extern void ix86_expand_vector_init (rtx, rtx);
 /* In winnt.c  */
index dafc60a..9b6e30e 100644 (file)
@@ -928,6 +928,7 @@ static int extended_reg_mentioned_1 (rtx *, void *);
 static bool ix86_rtx_costs (rtx, int, int, int *);
 static int min_insn_size (rtx);
 static tree ix86_md_asm_clobbers (tree clobbers);
+static bool ix86_must_pass_in_stack (enum machine_mode mode, tree type);
 
 #if defined (DO_GLOBAL_CTORS_BODY) && defined (HAS_INIT_SECTION)
 static void ix86_svr3_asm_out_constructor (rtx, int);
@@ -1071,6 +1072,8 @@ static void init_ext_80387_constants (void);
 #define TARGET_STRUCT_VALUE_RTX ix86_struct_value_rtx
 #undef TARGET_SETUP_INCOMING_VARARGS
 #define TARGET_SETUP_INCOMING_VARARGS ix86_setup_incoming_varargs
+#undef TARGET_MUST_PASS_IN_STACK
+#define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack
 
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg
@@ -1905,6 +1908,16 @@ ix86_function_arg_regno_p (int regno)
   return false;
 }
 
+/* Return if we do not know how to pass TYPE solely in registers.  */
+
+static bool
+ix86_must_pass_in_stack (enum machine_mode mode, tree type)
+{
+  if (must_pass_in_stack_var_size_or_pad (mode, type))
+    return true;
+  return (!TARGET_64BIT && type && mode == TImode);
+}
+
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
    for a call to a function whose data type is FNTYPE.
    For a library call, FNTYPE is 0.  */
@@ -2060,7 +2073,7 @@ classify_argument (enum machine_mode mode, tree type,
     return 0;
 
   if (mode != VOIDmode
-      && MUST_PASS_IN_STACK (mode, type))
+      && targetm.calls.must_pass_in_stack (mode, type))
     return 0;
 
   if (type && AGGREGATE_TYPE_P (type))
@@ -15848,15 +15861,6 @@ x86_emit_floatuns (rtx operands[2])
   emit_label (donelab);
 }
 
-/* Return if we do not know how to pass TYPE solely in registers.  */
-bool
-ix86_must_pass_in_stack (enum machine_mode mode, tree type)
-{
-   if (default_must_pass_in_stack (mode, type))
-     return true;
-   return (!TARGET_64BIT && type && mode == TImode);
-}
-
 /* Initialize vector TARGET via VALS.  */
 void
 ix86_expand_vector_init (rtx target, rtx vals)
index 631922b..33cd861 100644 (file)
@@ -1662,13 +1662,6 @@ enum reg_class
    which.  */
 #define REG_PARM_STACK_SPACE(FNDECL) 0
 
-/* Define as a C expression that evaluates to nonzero if we do not know how
-   to pass TYPE solely in registers.  The file expr.h defines a
-   definition that is usually appropriate, refer to expr.h for additional
-   documentation. If `REG_PARM_STACK_SPACE' is defined, the argument will be
-   computed in the stack and then loaded into a register.  */
-#define MUST_PASS_IN_STACK(MODE, TYPE)  ix86_must_pass_in_stack ((MODE), (TYPE))
-
 /* Value is the number of bytes of arguments automatically
    popped when returning from a subroutine call.
    FUNDECL is the declaration node of the function (as a tree),
index 3f03cab..51e410e 100644 (file)
@@ -402,11 +402,12 @@ static const struct attribute_spec ia64_attribute_table[] =
 #define TARGET_STRUCT_VALUE_RTX ia64_struct_value_rtx
 #undef TARGET_RETURN_IN_MEMORY
 #define TARGET_RETURN_IN_MEMORY ia64_return_in_memory
-
 #undef TARGET_SETUP_INCOMING_VARARGS
 #define TARGET_SETUP_INCOMING_VARARGS ia64_setup_incoming_varargs
 #undef TARGET_STRICT_ARGUMENT_NAMING
 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
+#undef TARGET_MUST_PASS_IN_STACK
+#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
 
 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR ia64_gimplify_va_arg
index 930266c..0e649e3 100644 (file)
@@ -1328,13 +1328,6 @@ enum reg_class
 #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
   ia64_function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED)
 
-/* Nonzero if we do not know how to pass TYPE solely in registers.  */
-
-#define MUST_PASS_IN_STACK(MODE, TYPE) \
-  ((TYPE) != 0                                                 \
-   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST             \
-       || TREE_ADDRESSABLE (TYPE)))
-
 /* A C type for declaring a variable that is used as the first argument of
    `FUNCTION_ARG' and other related values.  For some target machines, the type
    `int' suffices and can hold the number of bytes of argument so far.  */
index ab7a7b5..ac9b5d1 100644 (file)
@@ -2498,7 +2498,7 @@ function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
   /* We must pass by reference if we would be both passing in registers
      and the stack.  This is because any subsequent partial arg would be
      handled incorrectly in this case.  */
-  if (cum && MUST_PASS_IN_STACK (mode, type))
+  if (cum && targetm.calls.must_pass_in_stack (mode, type))
      {
        /* Don't pass the actual CUM to FUNCTION_ARG, because we would
          get double copies of any offsets generated for small structs
index 871369a..9bc3313 100644 (file)
@@ -137,12 +137,13 @@ static tree m32r_gimplify_va_arg_expr (tree, tree, tree *, tree *);
 
 #undef  TARGET_PROMOTE_PROTOTYPES
 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
-
 #undef  TARGET_RETURN_IN_MEMORY
 #define TARGET_RETURN_IN_MEMORY m32r_return_in_memory
-
 #undef  TARGET_SETUP_INCOMING_VARARGS
 #define TARGET_SETUP_INCOMING_VARARGS m32r_setup_incoming_varargs
+#undef  TARGET_MUST_PASS_IN_STACK
+#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
+
 #undef  TARGET_GIMPLIFY_VA_ARG_EXPR
 #define TARGET_GIMPLIFY_VA_ARG_EXPR m32r_gimplify_va_arg_expr
 
index 4a2e01f..6300967 100644 (file)
@@ -1033,12 +1033,6 @@ extern enum reg_class m32r_regno_reg_class[FIRST_PSEUDO_REGISTER];
    SIZE is the number of bytes of arguments passed on the stack.  */
 #define RETURN_POPS_ARGS(DECL, FUNTYPE, SIZE) 0
 
-/* Nonzero if we do not know how to pass TYPE solely in registers.  */
-#define MUST_PASS_IN_STACK(MODE, TYPE)                 \
-  ((TYPE) != 0                                         \
-   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST     \
-       || TREE_ADDRESSABLE (TYPE)))
-
 /* Define a data type for recording info about an argument list
    during the scan of that argument list.  This data type should
    hold all necessary information about the function itself
index 05272e7..ede6f93 100644 (file)
@@ -38,7 +38,6 @@ extern int          mcore_naked_function_p            (void);
 #ifdef HAVE_MACHINE_MODES
 extern int          mcore_function_arg_partial_nregs   (CUMULATIVE_ARGS, enum machine_mode, tree, int);
 extern int          mcore_num_arg_regs                 (enum machine_mode, tree);
-extern int          mcore_must_pass_on_stack           (enum machine_mode, tree);
 #endif /* HAVE_MACHINE_MODES */
 
 #ifdef RTX_CODE
index 97d06d0..7bad189 100644 (file)
@@ -192,6 +192,8 @@ static bool       mcore_return_in_memory    (tree, tree);
 
 #undef  TARGET_RETURN_IN_MEMORY
 #define TARGET_RETURN_IN_MEMORY                mcore_return_in_memory
+#undef  TARGET_MUST_PASS_IN_STACK
+#define TARGET_MUST_PASS_IN_STACK      must_pass_in_stack_var_size
 
 #undef  TARGET_SETUP_INCOMING_VARARGS
 #define TARGET_SETUP_INCOMING_VARARGS  mcore_setup_incoming_varargs
@@ -3001,20 +3003,6 @@ mcore_override_options (void)
     target_flags |= M340_BIT;
 }
 \f
-int
-mcore_must_pass_on_stack (enum machine_mode mode ATTRIBUTE_UNUSED, tree type)
-{
-  if (type == NULL)
-    return 0;
-
-  /* If the argument can have its address taken, it must
-     be placed on the stack.  */
-  if (TREE_ADDRESSABLE (type))
-    return 1;
-
-  return 0;
-}
-
 /* Compute the number of word sized registers needed to 
    hold a function argument of mode MODE and type TYPE.  */
 
@@ -3023,7 +3011,7 @@ mcore_num_arg_regs (enum machine_mode mode, tree type)
 {
   int size;
 
-  if (MUST_PASS_IN_STACK (mode, type))
+  if (targetm.calls.must_pass_in_stack (mode, type))
     return 0;
 
   if (type && mode == BLKmode)
@@ -3118,7 +3106,7 @@ mcore_function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode,
   if (! named)
     return 0;
 
-  if (MUST_PASS_IN_STACK (mode, type))
+  if (targetm.calls.must_pass_in_stack (mode, type))
     return 0;
 
   arg_reg = ROUND_REG (cum, mode);
@@ -3146,7 +3134,7 @@ mcore_function_arg_partial_nregs (CUMULATIVE_ARGS cum, enum machine_mode mode,
   if (named == 0)
     return 0;
 
-  if (MUST_PASS_IN_STACK (mode, type))
+  if (targetm.calls.must_pass_in_stack (mode, type))
     return 0;
       
   /* REG is not the *hardware* register number of the register that holds
index b6e5d87..b026c14 100644 (file)
@@ -662,9 +662,6 @@ extern const enum reg_class reg_class_from_letter[];
    On the MCore, only r4 can return results.  */
 #define FUNCTION_VALUE_REGNO_P(REGNO)  ((REGNO) == FIRST_RET_REG)
 
-#define        MUST_PASS_IN_STACK(MODE,TYPE)  \
-  mcore_must_pass_on_stack (MODE, TYPE)
-
 /* 1 if N is a possible register number for function argument passing.  */
 #define FUNCTION_ARG_REGNO_P(REGNO)  \
   ((REGNO) >= FIRST_PARM_REG && (REGNO) < (NPARM_REGS + FIRST_PARM_REG))
@@ -721,7 +718,7 @@ extern const enum reg_class reg_class_from_letter[];
    the argument itself.  The pointer is passed in whatever way is
    appropriate for passing a pointer to that type.  */
 #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
-  MUST_PASS_IN_STACK (MODE, TYPE)
+  targetm.calls.must_pass_in_stack (MODE, TYPE)
 
 /* For an arg passed partly in registers and partly in memory,
    this is the number of registers used.
index cad6e8d..cb470b4 100644 (file)
@@ -738,6 +738,8 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
 #define TARGET_SETUP_INCOMING_VARARGS mips_setup_incoming_varargs
 #undef TARGET_STRICT_ARGUMENT_NAMING
 #define TARGET_STRICT_ARGUMENT_NAMING mips_strict_argument_naming
+#undef TARGET_MUST_PASS_IN_STACK
+#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
@@ -3552,7 +3554,7 @@ mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
        even_reg_p = true;
     }
 
-  if (mips_abi != ABI_EABI && MUST_PASS_IN_STACK (mode, type))
+  if (mips_abi != ABI_EABI && targetm.calls.must_pass_in_stack (mode, type))
     /* This argument must be passed on the stack.  Eat up all the
        remaining registers.  */
     info->reg_offset = MAX_ARGS_IN_REGISTERS;
@@ -4284,7 +4286,7 @@ mips_va_arg (tree valist, tree type)
 
       /* If arguments of type TYPE must be passed on the stack,
         set MIN_OFFSET to the offset of the first stack parameter.  */
-      if (!MUST_PASS_IN_STACK (TYPE_MODE (type), type))
+      if (!targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
        min_offset = 0;
       else if (TARGET_NEWABI)
        min_offset = current_function_pretend_args_size;
index 829168d..04e6ee4 100644 (file)
@@ -2364,14 +2364,6 @@ typedef struct mips_args {
   (mips_abi == ABI_EABI && (NAMED)                                     \
    && FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED))
 
-/* Modified version of the macro in expr.h.  Only return true if
-   the type has a variable size or if the front end requires it
-   to be passed by reference.  */
-#define MUST_PASS_IN_STACK(MODE,TYPE)                  \
-  ((TYPE) != 0                                         \
-   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST     \
-       || TREE_ADDRESSABLE (TYPE)))
-
 /* True if using EABI and varargs can be passed in floating-point
    registers.  Under these conditions, we need a more complex form
    of va_list, which tracks GPR, FPR and stack arguments separately.  */
index 9c7fb62..569acc2 100644 (file)
@@ -578,7 +578,7 @@ mmix_function_arg (const CUMULATIVE_ARGS *argsp,
       : NULL_RTX;
 
   return (argsp->regs < MMIX_MAX_ARGS_IN_REGS
-         && !MUST_PASS_IN_STACK (mode, type)
+         && !targetm.calls.must_pass_in_stack (mode, type)
          && (GET_MODE_BITSIZE (mode) <= 64
              || argsp->lib
              || TARGET_LIBFUNC))
@@ -599,10 +599,10 @@ mmix_function_arg_pass_by_reference (const CUMULATIVE_ARGS *argsp,
                                     tree type,
                                     int named ATTRIBUTE_UNUSED)
 {
-  /* FIXME: Check: I'm not sure the MUST_PASS_IN_STACK check is
+  /* FIXME: Check: I'm not sure the must_pass_in_stack check is
      necessary.  */
   return
-    MUST_PASS_IN_STACK (mode, type)
+    targetm.calls.must_pass_in_stack (mode, type)
     || (MMIX_FUNCTION_ARG_SIZE (mode, type) > 8
        && !TARGET_LIBFUNC
        && !argsp->lib);
index 7d2ca84..5d68fa7 100644 (file)
@@ -740,7 +740,7 @@ typedef struct { int regs; int lib; } CUMULATIVE_ARGS;
 
 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED)           \
  ((CUM).regs                                                   \
-  = ((MUST_PASS_IN_STACK (MODE, TYPE))                         \
+  = ((targetm.calls.must_pass_in_stack (MODE, TYPE))           \
      || (MMIX_FUNCTION_ARG_SIZE (MODE, TYPE) > 8               \
         && !TARGET_LIBFUNC && !(CUM).lib))                     \
   ? (MMIX_MAX_ARGS_IN_REGS) + 1                                        \
index ccc8f28..bbc27bd 100644 (file)
@@ -265,6 +265,8 @@ static size_t n_deferred_plabels = 0;
 #define TARGET_STRUCT_VALUE_RTX pa_struct_value_rtx
 #undef TARGET_RETURN_IN_MEMORY
 #define TARGET_RETURN_IN_MEMORY pa_return_in_memory
+#undef TARGET_MUST_PASS_IN_STACK
+#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
 
 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
 #define TARGET_EXPAND_BUILTIN_SAVEREGS hppa_builtin_saveregs
index f82e09b..dd6f356 100644 (file)
@@ -890,12 +890,6 @@ struct hppa_args {int words, nargs_prototype, incoming, indirect; };
 #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
   function_arg (&CUM, MODE, TYPE, NAMED)
 
-/* Nonzero if we do not know how to pass TYPE solely in registers.  */
-#define MUST_PASS_IN_STACK(MODE,TYPE) \
-  ((TYPE) != 0                                                 \
-   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST             \
-       || TREE_ADDRESSABLE (TYPE)))
-
 /* For an arg passed partly in registers and partly in memory,
    this is the number of registers used.
    For args passed entirely in registers or entirely in memory, zero.  */
index 8875207..38196d7 100644 (file)
 #define AGGREGATE_PADDING_FIXED 1
 #define AGGREGATES_PAD_UPWARD_ALWAYS 1
 
-/* We don't want anything in the reg parm area being passed on the
-   stack.  */
-#define MUST_PASS_IN_STACK(MODE, TYPE)                         \
-   ((TYPE) != 0                                                        \
-    && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST            \
-       || TREE_ADDRESSABLE (TYPE)))
-
 /* Specify padding for the last element of a block move between
    registers and memory.  FIRST is nonzero if this is the only
    element.  */
index a63cb5f..5ebc19c 100644 (file)
 #define AGGREGATE_PADDING_FIXED TARGET_64BIT
 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
 
-/* We don't want anything in the reg parm area being passed on the
-   stack.  */
-#define MUST_PASS_IN_STACK(MODE, TYPE)                         \
-  ((TARGET_64BIT                                               \
-    && (TYPE) != 0                                             \
-    && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST            \
-       || TREE_ADDRESSABLE (TYPE)))                            \
-   || (!TARGET_64BIT                                           \
-       && default_must_pass_in_stack ((MODE), (TYPE))))
-
 /* Specify padding for the last element of a block move between
    registers and memory.  FIRST is nonzero if this is the only
    element.  */
index 0722ed7..ea81e8b 100644 (file)
@@ -744,6 +744,7 @@ static tree get_prev_label (tree function_name);
 
 static tree rs6000_build_builtin_va_list (void);
 static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *);
+static bool rs6000_must_pass_in_stack (enum machine_mode, tree);
 
 /* Hash table stuff for keeping track of TOC entries.  */
 
@@ -948,6 +949,8 @@ static const char alt_reg_names[][8] =
 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
 #undef TARGET_SPLIT_COMPLEX_ARG
 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
+#undef TARGET_MUST_PASS_IN_STACK
+#define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
 
 #undef TARGET_BUILD_BUILTIN_VA_LIST
 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
@@ -4525,6 +4528,17 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
       }
 }
 \f
+/* Return true if TYPE must be passed on the stack and not in registers.  */
+
+static bool
+rs6000_must_pass_in_stack (enum machine_mode mode, tree type)
+{
+  if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
+    return must_pass_in_stack_var_size (mode, type);
+  else
+    return must_pass_in_stack_var_size_or_pad (mode, type);
+}
+
 /* If defined, a C expression which determines whether, and in which
    direction, to pad out an argument with extra space.  The value
    should be of type `enum direction': either `upward' to pad above
@@ -5261,7 +5275,7 @@ setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
       save_area = virtual_incoming_args_rtx;
       cfun->machine->sysv_varargs_p = 0;
 
-      if (MUST_PASS_IN_STACK (mode, type))
+      if (targetm.calls.must_pass_in_stack (mode, type))
        first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
     }
 
index dc16c61..4003f16 100644 (file)
@@ -436,6 +436,8 @@ static tree sh_gimplify_va_arg_expr (tree, tree, tree *, tree *);
 #define TARGET_STRICT_ARGUMENT_NAMING sh_strict_argument_naming
 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED sh_pretend_outgoing_varargs_named
+#undef TARGET_MUST_PASS_IN_STACK
+#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
 
 #undef TARGET_BUILD_BUILTIN_VA_LIST
 #define TARGET_BUILD_BUILTIN_VA_LIST sh_build_builtin_va_list
@@ -6316,7 +6318,7 @@ sh_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
   HOST_WIDE_INT size, rsize;
   tree tmp, pptr_type_node;
   tree addr, lab_over, result = NULL;
-  int pass_by_ref = MUST_PASS_IN_STACK (TYPE_MODE (type), type);
+  int pass_by_ref = targetm.calls.must_pass_in_stack (TYPE_MODE (type), type);
 
   if (pass_by_ref)
     type = build_pointer_type (type);
index 360ba4a..a76bda1 100644 (file)
@@ -1725,14 +1725,6 @@ extern enum reg_class reg_class_from_letter[];
    On SHcompact, the call trampoline pops arguments off the stack.  */
 #define CALL_POPS_ARGS(CUM) (TARGET_SHCOMPACT ? (CUM).stack_regs * 8 : 0)
 
-/* Nonzero if we do not know how to pass TYPE solely in registers.
-   Values that come in registers with inconvenient padding are stored
-   to memory at the function start.  */
-
-#define MUST_PASS_IN_STACK(MODE,TYPE)                  \
-  ((TYPE) != 0                                         \
-   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST     \
-       || TREE_ADDRESSABLE (TYPE)))
 /* Some subroutine macros specific to this machine.  */
 
 #define BASE_RETURN_VALUE_REG(MODE) \
@@ -2046,7 +2038,7 @@ struct sh_args {
    registers are passed by reference, so that an SHmedia trampoline
    loads them into the full 64-bits registers.  */
 #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM,MODE,TYPE,NAMED) \
-  (MUST_PASS_IN_STACK ((MODE), (TYPE)) \
+  (targetm.calls.must_pass_in_stack ((MODE), (TYPE)) \
    || SHCOMPACT_BYREF ((CUM), (MODE), (TYPE), (NAMED)))
 
 #define SHCOMPACT_BYREF(CUM, MODE, TYPE, NAMED) \
index e87b29e..8f73f1b 100644 (file)
@@ -434,6 +434,8 @@ enum processor_type sparc_cpu;
 #define TARGET_STRUCT_VALUE_RTX sparc_struct_value_rtx
 #undef TARGET_RETURN_IN_MEMORY
 #define TARGET_RETURN_IN_MEMORY sparc_return_in_memory
+#undef TARGET_MUST_PASS_IN_STACK
+#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
 
 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
 #define TARGET_EXPAND_BUILTIN_SAVEREGS sparc_builtin_saveregs
index d0f75d2..18de27f 100644 (file)
@@ -1713,13 +1713,6 @@ init_cumulative_args (& (CUM), (FNTYPE), (LIBNAME), (FNDECL));
 #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
 function_arg_advance (& (CUM), (MODE), (TYPE), (NAMED))
 
-/* Nonzero if we do not know how to pass TYPE solely in registers.  */
-
-#define MUST_PASS_IN_STACK(MODE,TYPE)                  \
-  ((TYPE) != 0                                         \
-   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST     \
-       || TREE_ADDRESSABLE (TYPE)))
-
 /* Determine where to put an argument to a function.
    Value is zero to push the argument on the stack,
    or a hard register in which to store the argument.
index e2fbf02..7f2a2fe 100644 (file)
@@ -1229,7 +1229,7 @@ xstormy16_function_arg (CUMULATIVE_ARGS cum, enum machine_mode mode,
 {
   if (mode == VOIDmode)
     return const0_rtx;
-  if (MUST_PASS_IN_STACK (mode, type)
+  if (targetm.calls.must_pass_in_stack (mode, type)
       || cum + XSTORMY16_WORD_SIZE (type, mode) > NUM_ARGUMENT_REGISTERS)
     return 0;
   return gen_rtx_REG (mode, cum + 2);
@@ -1325,7 +1325,7 @@ xstormy16_expand_builtin_va_arg (tree valist, tree type, tree *pre_p,
   count = build (COMPONENT_REF, TREE_TYPE (f_count), valist, f_count,
                 NULL_TREE);
 
-  must_stack = MUST_PASS_IN_STACK (TYPE_MODE (type), type);
+  must_stack = targetm.calls.must_pass_in_stack (TYPE_MODE (type), type);
   size_tree = round_up (size_in_bytes (type), UNITS_PER_WORD);
   gimplify_expr (&size_tree, pre_p, NULL, is_gimple_val, fb_rvalue);
   
index f21930d..b3bd840 100644 (file)
@@ -255,6 +255,8 @@ static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
 #define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
 #undef TARGET_SPLIT_COMPLEX_ARG
 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
+#undef TARGET_MUST_PASS_IN_STACK
+#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
 
 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
 #define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
@@ -2540,13 +2542,13 @@ xtensa_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p,
   /* Check if the argument is in registers:
 
      if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
-         && !MUST_PASS_IN_STACK (type))
+         && !must_pass_in_stack (type))
         __array = (AP).__va_reg; */
 
   array = create_tmp_var (ptr_type_node, NULL);
 
   lab_over = NULL;
-  if (!MUST_PASS_IN_STACK (VOIDmode, type))
+  if (!targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
     {
       lab_false = create_artificial_label ();
       lab_over = create_artificial_label ();
index 41e64c6..1321448 100644 (file)
@@ -774,22 +774,6 @@ typedef struct xtensa_args
       ? PARM_BOUNDARY                                                  \
       : GET_MODE_ALIGNMENT (MODE)))
 
-/* Nonzero if we do not know how to pass TYPE solely in registers.
-   We cannot do so in the following cases:
-
-   - if the type has variable size
-   - if the type is marked as addressable (it is required to be constructed
-     into the stack)
-
-   This differs from the default in that it does not check if the padding
-   and mode of the type are such that a copy into a register would put it
-   into the wrong part of the register.  */
-
-#define MUST_PASS_IN_STACK(MODE, TYPE)                                 \
-  ((TYPE) != 0                                                         \
-   && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST                     \
-       || TREE_ADDRESSABLE (TYPE)))
-
 /* Profiling Xtensa code is typically done with the built-in profiling
    feature of Tensilica's instruction set simulator, which does not
    require any compiler support.  Profiling code on a real (i.e.,
index 3bc86f3..28dfe7d 100644 (file)
@@ -3669,9 +3669,9 @@ where some arguments are usually passed in registers, is to cause
 nameless arguments to be passed on the stack instead.  This is done
 by making @code{FUNCTION_ARG} return 0 whenever @var{named} is 0.
 
-@cindex @code{MUST_PASS_IN_STACK}, and @code{FUNCTION_ARG}
+@cindex @code{TARGET_MUST_PASS_IN_STACK}, and @code{FUNCTION_ARG}
 @cindex @code{REG_PARM_STACK_SPACE}, and @code{FUNCTION_ARG}
-You may use the macro @code{MUST_PASS_IN_STACK (@var{mode}, @var{type})}
+You may use the hook @code{targetm.calls.must_pass_in_stack}
 in the definition of this macro to determine if this argument is of a
 type that must be passed in the stack.  If @code{REG_PARM_STACK_SPACE}
 is not defined and @code{FUNCTION_ARG} returns nonzero for such an
@@ -3680,12 +3680,12 @@ defined, the argument will be computed in the stack and then loaded into
 a register.
 @end defmac
 
-@defmac MUST_PASS_IN_STACK (@var{mode}, @var{type})
-Define as a C expression that evaluates to nonzero if we do not know how
-to pass TYPE solely in registers.  The file @file{expr.h} defines a
+@deftypefn {Target Hook} bool TARGET_MUST_PASS_IN_STACK (enum machine_mode @var{mode}, tree @var{type})
+This target hook should return @code{true} if we should not pass @var{type}
+solely in registers.  The file @file{expr.h} defines a
 definition that is usually appropriate, refer to @file{expr.h} for additional
 documentation.
-@end defmac
+@end deftypefn
 
 @defmac FUNCTION_INCOMING_ARG (@var{cum}, @var{mode}, @var{type}, @var{named})
 Define this macro if the target machine has ``register windows'', so
@@ -3734,7 +3734,7 @@ definition of this macro might be
 @smallexample
 #define FUNCTION_ARG_PASS_BY_REFERENCE\
 (CUM, MODE, TYPE, NAMED)  \
-  MUST_PASS_IN_STACK (MODE, TYPE)
+  targetm.calls.must_pass_in_stack (MODE, TYPE)
 @end smallexample
 @c this is *still* too long.  --mew 5feb93
 @end defmac
index 55106a2..687b6e3 100644 (file)
@@ -218,12 +218,6 @@ do {                                                       \
 tree split_complex_types (tree);
 tree split_complex_values (tree);
 
-/* Nonzero if we do not know how to pass TYPE solely in registers.  */
-extern bool default_must_pass_in_stack (enum machine_mode, tree);
-#ifndef MUST_PASS_IN_STACK
-#define MUST_PASS_IN_STACK(MODE,TYPE) default_must_pass_in_stack(MODE, TYPE)
-#endif
-
 /* Supply a default definition of STACK_SAVEAREA_MODE for emit_stack_save.
    Normally move_insn, so Pmode stack pointer.  */
 
index 19549b1..19698f9 100644 (file)
@@ -2356,7 +2356,8 @@ assign_parm_find_entry_rtl (struct assign_parm_data_all *all,
 
   /* If this parameter was passed both in registers and in the stack, use
      the copy on the stack.  */
-  if (MUST_PASS_IN_STACK (data->promoted_mode, data->passed_type))
+  if (targetm.calls.must_pass_in_stack (data->promoted_mode,
+                                       data->passed_type))
     entry_parm = 0;
 
   if (entry_parm)
index 367c51e..ce8f3ec 100644 (file)
@@ -584,7 +584,8 @@ extern int snprintf (char *, size_t, const char *, ...);
        PROMOTE_FUNCTION_RETURN PROMOTE_PROTOTYPES STRUCT_VALUE_REGNUM  \
        SETUP_INCOMING_VARARGS EXPAND_BUILTIN_SAVEREGS                  \
        DEFAULT_SHORT_ENUMS SPLIT_COMPLEX_ARGS MD_ASM_CLOBBERS          \
-       HANDLE_PRAGMA_REDEFINE_EXTNAME HANDLE_PRAGMA_EXTERN_PREFIX
+       HANDLE_PRAGMA_REDEFINE_EXTNAME HANDLE_PRAGMA_EXTERN_PREFIX      \
+       MUST_PASS_IN_STACK
 
 /* Other obsolete target macros, or macros that used to be in target
    headers and were not used, and may be obsolete or may never have
index 14943da..329e44b 100644 (file)
@@ -364,6 +364,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 #define TARGET_LATE_RTL_PROLOGUE_EPILOGUE false
 
+#define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size_or_pad
+
 #define TARGET_CALLS {                                         \
    TARGET_PROMOTE_FUNCTION_ARGS,                               \
    TARGET_PROMOTE_FUNCTION_RETURN,                             \
@@ -376,6 +378,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    TARGET_STRICT_ARGUMENT_NAMING,                              \
    TARGET_PRETEND_OUTGOING_VARARGS_NAMED,                      \
    TARGET_SPLIT_COMPLEX_ARG,                                   \
+   TARGET_MUST_PASS_IN_STACK                                   \
    }
 
 
index befe67b..2c38dc5 100644 (file)
@@ -462,6 +462,12 @@ struct gcc_target
     /* Given a complex type T, return true if a parameter of type T
        should be passed as two scalars.  */
     bool (* split_complex_arg) (tree type);
+
+    /* Return true if type T, mode MODE, may not be passed in registers,
+       but must be passed on the stack.  */
+    /* ??? This predicate should be applied strictly after pass-by-reference.
+       Need audit to verify that this is the case.  */
+    bool (* must_pass_in_stack) (enum machine_mode mode, tree t);
   } calls;
 
   /* Functions specific to the C++ frontend.  */
index 75f4f28..d2b06b3 100644 (file)
@@ -3567,6 +3567,8 @@ extern int call_expr_flags (tree);
 
 extern int setjmp_call_p (tree);
 extern bool alloca_call_p (tree);
+extern bool must_pass_in_stack_var_size (enum machine_mode, tree);
+extern bool must_pass_in_stack_var_size_or_pad (enum machine_mode, tree);
 
 /* In attribs.c.  */