target-def.h (TARGET_MUST_PASS_IN_STACK): New.
authorRichard Henderson <rth@redhat.com>
Tue, 13 Jul 2004 07:45:09 +0000 (00:45 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Tue, 13 Jul 2004 07:45:09 +0000 (00:45 -0700)
* 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.

From-SVN: r84606

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 8372af0892a465644f93c4f259ca6c3b6085f691..6c2ef13d44b18cfde53886578868615385f147e0 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 c54ab48a7d85cb0168ad3a63e289eb2e2fb8e8b5..e1281624a05e70df1505abf8007e0005341fcfde 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 19bf341bfdf42fb95a82687e5b8faac195f65986..422d6c6a44c7bbb9dad1d61d072f84501e0a4855 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 8dbdeb03187836d2e021d59da585d4c13cb76c30..e142e5e177ae151efe16b03529d020c88125fbe0 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 d1dfe91262275e0a77568800f63b3f9288b608f3..7c9a6073fa653e03452922d424c17ac307905d67 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 f7058f3ff399fa2a85827ee6e33364546eae33f5..b062d616c0085e2783d31be3efe90e2d2bceb3d9 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 dff0da4ed5dfe27b6e66d4c31b0ef4ada0812b1a..bc384ee2e14960022a919419ec903483e12988b8 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 3eabb51ba6230b912b678537a9512ce93b693f2b..252992b0376eb072a78c342b5c8fa4562acb3e57 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 d0213d276513e07014933750d6599ad6790652ce..017acfd40d28c360f6547b312bf29a32a21ad5cd 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 1260075e3bb75e07739948838a5a7a3924280947..b8bec8e4fc472b628328d65733213d01939548c7 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 98663202297ceeab4fbbd27a6f1bd0c3755be0f6..4d05bd45f38eb00a6567ea673aeec8873cb2adf6 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 29d22e44fb9ccbe80547c1efb984906028ebe4bd..493ebc76a4a830adb86c49ea65af983d48287b6b 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 6cf6fe2ff0349791a660cd3f9d96a807106a4927..7fb122dc6d8cbcff7d9d66d676fd1eb8c7461d14 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 dafc60afe41bff2c0d82e87c1d1a50af03730b1a..9b6e30e8fd86e734c0a6e6bcd0584df983327b84 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 631922b46c32f93d750e9ff06bb17889c761b6a5..33cd861819fd9e25e27e385a04ad6c97ce51373b 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 3f03cab969773eab26199ea68e1591d3c1334249..51e410eb2c8058d27479a3989d9a81e2687da229 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 930266c6f85a5d1f24b75345d944b82ee4969d30..0e649e3442e39e7aeb99b8991e7d345c44d3b4ed 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 ab7a7b52d11203d08554b694c48958764a647cc8..ac9b5d138ee7896aad01d7228108642884166703 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 871369a9e98137c07ee6bd9b9faba582a232db86..9bc3313badcaa1589da3b411bc490d516331f816 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 4a2e01f51da34b7feb5a72ca2c4694f275832307..6300967afc03802a2adc746e1065f445082a8f06 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 05272e7d9b752892bee353f953e1084ba84d29cc..ede6f93a3dbf27e641ad8a589bae38e5585ea326 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 97d06d0786428f7dae558fdf1b3daa98f2f940d1..7bad189422edd3d8c4eb6c67cc2603458ded5394 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 b6e5d87a42a30c1999178748a6631855c35aa73b..b026c1416b92810dd10ab8e6bdc16614a694705f 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 cad6e8d049cf8c8f41266bb6fcd8c8419e81c0a5..cb470b4c2240e00ddede2740cb3b455f0ff6d915 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 829168d6867fe3b337163f058f496a8dac1a114b..04e6ee4e8c6b4b614624174829d8d0332aba435e 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 9c7fb62652fdc559e5cfb8616edd240f61e8814a..569acc20183d6ad56c367585c9d231b534851f54 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 7d2ca84f626f15ae77876dcdcd48ba000d2a29e9..5d68fa716c55aa2ac73586cdb9752521db5c9a29 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 ccc8f288fb692dccd7e18124029c98acfc37a33d..bbc27bdf877b7fdb0927a37dbbf988c34005622a 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 f82e09b1687193749e14591a94d7a2aa8d89401b..dd6f356f3d09dbef283e87268d8000aad1b3e59f 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 887520797729e1f8560de82832942cdaaac652b6..38196d7f324af8c430219c483ab0a8cffa774542 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 a63cb5fcff17a0fcdf7b6e0734693a7316484370..5ebc19c818b6a8f75bfd01bf7a80e81187d0f326 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 0722ed7502192ffd8b5f99a152a15a59b372d8bc..ea81e8ba73489b3afc40d565a6b16b15aec5f6c5 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 dc16c61931bcae6d7bc7a85bddd30faae1200adf..4003f1676d6f682b0bafceea570a85eec5dea1f5 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 360ba4aecc0b3be36ceb03baecfe7b2e759f51e1..a76bda1238ffd6ac4ced8b7c162d3ffd2314b44c 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 e87b29e994d67cc4974390cb93d08f025e8bef39..8f73f1b15f6af9f78ae4d8954ba04ec88b91c571 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 d0f75d2382f294222cfaa295d15c2f17ae21f4bb..18de27f86ab9e9beeb6e9d7ab42bd7681209db2d 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 e2fbf0279dc6f7ed1550b2bd6c051e504d6f6daf..7f2a2feb7fe80dd3060d31de912e26559b278784 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 f21930d96678515ca0a70957ce8238fbcb75e709..b3bd840ce04649596d2bd107141cff2417e7e310 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 41e64c6278be90a1b571bc5fce96f4b5a59a06eb..1321448dcd129c3f0ce7b77f5d9a083ed9310076 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 3bc86f33982a5b8ff41281faf7795f2e77f1cb38..28dfe7d9e75d3ed6e1eac0d7ac694a8d7204fcae 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 55106a20572540498fbc7950da91abf8d18a16e5..687b6e3943f47fe0e68ffa9511753e7ebf426386 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 19549b1b800a0c50103b8def30234f0add267949..19698f99214bea47d27da61811b3eb2694f2d109 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 367c51ed849adf151f206298cce9f7a5e3f30f9e..ce8f3ecd825b21ff11a04f916bf77fca2fce41a3 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 14943da383f26d533c8399bafbe96209fcbab534..329e44b9b97c1ede5ab4fdbe920c06f82c1b91cb 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 befe67bf906f1664b688bb152a50cf4b2cafa76e..2c38dc5dcc6af23d2025381a14afe47028f8e8ca 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 75f4f285add913b970c99d24e25138b8bf6fbe90..d2b06b3da15e7b6559f6f2edf01f43d029120df3 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.  */