OSDN Git Service

* calls.c (initialize_argument_information): If an argument has no
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 27 Aug 2003 07:05:18 +0000 (07:05 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 27 Aug 2003 07:05:18 +0000 (07:05 +0000)
stack space associated with it, and BLOCK_REG_PADDING is defined,
use it to decide at which end the argument should be padded.
* function.c (assign_parms): Allocate BLKmode stack slots.
* config/mips/mips-protos.h (mips_pad_arg_upward): Declare.
(mips_pad_reg_upward): Declare.
* config/mips/mips.h (PAD_VARARGS_DOWN): Use FUNCTION_ARG_PADDING.
(CUMULATIVE_ARGS): Remove num_adjusts and adjusts.
(FUNCTION_ARG_PADDING): Use mips_pad_arg_upward.
(BLOCK_REG_PADDING): Use mips_pad_reg_upward.
* config/mips/mips.c (struct mips_arg_info): Remove struct_p.
(mips_expand_call): Remove code for generating structure shifts.
(mips_arg_info): Don't set struct_p.  Don't set fpr_p for non-float
types unless using the EABI.
(function_arg_advance): Don't generate shift instructions.
(function_arg): Don't return them.  Don't short-circuit the
check for double structure chunks for DFmode arguments.
(mips_pad_arg_upward, mips_pad_reg_upward): New functions.
(mips_expand_prologue): Remove code to emit structure shifts.
* config/mips/irix6-libc-compat.c: Remove workarounds for buggy
structure passing (inet_ntoa, inet_lnaof, inet_netof).  Update
comments to say that only structure returns are a problem.

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

gcc/ChangeLog
gcc/calls.c
gcc/config/mips/irix6-libc-compat.c
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/function.c

index 873f3f9..ef8624f 100644 (file)
@@ -1,3 +1,28 @@
+2003-08-27  Richard Sandiford  <rsandifo@redhat.com>
+
+       * calls.c (initialize_argument_information): If an argument has no
+       stack space associated with it, and BLOCK_REG_PADDING is defined,
+       use it to decide at which end the argument should be padded.
+       * function.c (assign_parms): Allocate BLKmode stack slots.
+       * config/mips/mips-protos.h (mips_pad_arg_upward): Declare.
+       (mips_pad_reg_upward): Declare.
+       * config/mips/mips.h (PAD_VARARGS_DOWN): Use FUNCTION_ARG_PADDING.
+       (CUMULATIVE_ARGS): Remove num_adjusts and adjusts.
+       (FUNCTION_ARG_PADDING): Use mips_pad_arg_upward.
+       (BLOCK_REG_PADDING): Use mips_pad_reg_upward.
+       * config/mips/mips.c (struct mips_arg_info): Remove struct_p.
+       (mips_expand_call): Remove code for generating structure shifts.
+       (mips_arg_info): Don't set struct_p.  Don't set fpr_p for non-float
+       types unless using the EABI.
+       (function_arg_advance): Don't generate shift instructions.
+       (function_arg): Don't return them.  Don't short-circuit the
+       check for double structure chunks for DFmode arguments.
+       (mips_pad_arg_upward, mips_pad_reg_upward): New functions.
+       (mips_expand_prologue): Remove code to emit structure shifts.
+       * config/mips/irix6-libc-compat.c: Remove workarounds for buggy
+       structure passing (inet_ntoa, inet_lnaof, inet_netof).  Update
+       comments to say that only structure returns are a problem.
+
 2003-08-26  Nathanael Nerode  <neroden@gcc.gnu.org>
 
        * fixinc/tests/base/string.h, fixinc/tests/base/sys/regset.h:
index 900290f..50fa592 100644 (file)
@@ -1238,6 +1238,14 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
 #endif
                             args[i].pass_on_stack ? 0 : args[i].partial,
                             fndecl, args_size, &args[i].locate);
+#ifdef BLOCK_REG_PADDING
+      else
+       /* The argument is passed entirely in registers.  See at which
+          end it should be padded.  */
+       args[i].locate.where_pad =
+         BLOCK_REG_PADDING (mode, type,
+                            int_size_in_bytes (type) <= UNITS_PER_WORD);
+#endif
 
       /* Update ARGS_SIZE, the total stack space for args so far.  */
 
index ce3b63a..59a148a 100644 (file)
@@ -1,4 +1,4 @@
-/* Compensate for inconsistent structure passing conventions on IRIX 6.  */
+/* Compensate for inconsistent structure return conventions on IRIX 6.  */
 /* Compile this one with gcc.  */
 /* Copyright (C) 2001  Free Software Foundation, Inc.
 
@@ -28,7 +28,7 @@ along with GNU CC; see the file COPYING.  If not, write to
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
-/* GCC doesn't correctly implement the structure and union passing and return
+/* GCC doesn't correctly implement the structure and union return
    conventions of the N32 and N64 ABIs on IRIX 6, as described in the
    MIPSpro N32 ABI Handbook, ch. 2, Calling Convention Implementations, p.7.
    The ABI requires that structures (or trailing parts of structures) smaller
@@ -38,17 +38,15 @@ Boston, MA 02111-1307, USA.  */
    While GCC is internally consistent, calling routines compiled with a
    compiler that does implement the documented ABI (like SGIs MIPSpro C
    compiler) doesn't work.  This is primarily an issue for system libraries
-   like libc.  Fortunately, there exist only very few routines that take
-   structure value arguments or return structures by value, so until the
-   underlying bug is fixed, it is possible to work around it by providing
-   wrapper functions for the few affected routines that compensate for the
-   inconsistent alignment.
+   like libc.  Fortunately, there exist only very few routines that return
+   structures by value, so until the underlying bug is fixed, it is possible
+   to work around it by providing wrappers for the few affected routines.
 
    These wrappers rely on the fact that e.g. libc contains weak versions of
    those routines, and the real implementation is provided by _-prefixed
    variants.  So we can provide our own versions, which will only be linked
    if the application uses any of the affected functions, calling the private
-   variants after shifting the arguments or results as required.
+   variants and then shifting the result as required.
 
    This is a rewrite of code created by Andy Polyakov.  */
 
@@ -61,62 +59,17 @@ Boston, MA 02111-1307, USA.  */
 
 #if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
 
-/* The affected arguments need to be shifted by
+/* The affected return values need to be shifted by
 
-       BITS_PER_WORD - (sizeof (arg) * BITS_PER_UNIT).
+       BITS_PER_WORD - (sizeof (value) * BITS_PER_UNIT).
 
-   Since only 32-bit args and results are involved, the shift count is
-   always 32.  */
+   Since only 32-bit results are involved, the shift count is always 32.  */
 #define SHIFT_BITS     32
 
-extern machreg_t inet_ntoa (machreg_t);
-extern machreg_t inet_lnaof (machreg_t);
-extern machreg_t inet_netof (machreg_t);
-extern machreg_t inet_makeaddr (machreg_t, machreg_t);
-
-extern machreg_t _inet_ntoa (machreg_t);
-extern machreg_t _inet_lnaof (machreg_t);
-extern machreg_t _inet_netof (machreg_t);
 extern machreg_t _inet_makeaddr (machreg_t, machreg_t);
 
 /* <arpa/inet.h> has
 
-       char *inet_ntoa (struct in_addr);
-
-   on both IRIX 6.2 and 6.5, with struct in_addr containing a 32-bit int.  */
-
-machreg_t
-inet_ntoa (machreg_t in)
-{
-  return _inet_ntoa (in << SHIFT_BITS);
-}
-
-/* <arpa/inet.h> has
-
-       unsigned long inet_lnaof (struct in_addr);              (IRIX 6.2)
-       in_addr_t inet_lnaof (struct in_addr);                  (IRIX 6.5)
-
-   in_addr_t is a 32-bit int.  */
-
-machreg_t
-inet_lnaof (machreg_t in)
-{
-  return _inet_lnaof (in << SHIFT_BITS);
-}
-
-/* <arpa/inet.h> has
-
-       unsigned long inet_netof (struct in_addr);              (IRIX 6.2)
-       in_addr_t inet_netof (struct in_addr);                  (IRIX 6.5)  */
-
-machreg_t
-inet_netof (machreg_t in)
-{
-  return _inet_netof (in << SHIFT_BITS);
-}
-
-/* <arpa/inet.h> has
-
        struct in_addr inet_makeaddr (int, int);                (IRIX 6.2)
        struct in_addr inet_makeaddr (in_addr_t, in_addr_t);    (IRIX 6.5)  */
 
@@ -126,23 +79,4 @@ inet_makeaddr (machreg_t net, machreg_t lna)
   return _inet_makeaddr (net, lna) >> SHIFT_BITS;
 }
 
-#if _MIPS_SIM == _ABIN32
-extern machreg_t semctl (machreg_t, machreg_t, machreg_t, machreg_t);
-extern machreg_t _semctl (machreg_t, machreg_t, machreg_t, machreg_t);
-
-/* <sys/sem.h> has
-
-       int semctl (int, int, int, ...);
-
-   where the variadic argument is union semun if used.  union semun contains
-   an int and two pointers, so the union is already 64 bits wide under the
-   N64 ABI and alignment is not an issue.  */
-
-machreg_t
-semctl (machreg_t semid, machreg_t semnum, machreg_t cmd, machreg_t arg)
-{
-  return _semctl(semid, semnum, cmd, arg << SHIFT_BITS);
-}
-#endif /* _ABIN32 */
-
 #endif /* _ABIN32 || _ABI64 */
index 9e053a6..89a8cb2 100644 (file)
@@ -80,6 +80,8 @@ extern struct rtx_def *function_arg (const CUMULATIVE_ARGS *,
                                     enum machine_mode, tree, int);
 extern int function_arg_partial_nregs (const CUMULATIVE_ARGS *,
                                       enum machine_mode, tree, int);
+extern bool mips_pad_arg_upward (enum machine_mode, tree);
+extern bool mips_pad_reg_upward (enum machine_mode, tree);
 extern int mips_setup_incoming_varargs (const CUMULATIVE_ARGS *,
                                        enum machine_mode, tree, int);
 extern tree mips_build_va_list (void);
index 5f882c2..37fd534 100644 (file)
@@ -317,9 +317,6 @@ struct machine_function GTY(()) {
 /* Information about a single argument.  */
 struct mips_arg_info
 {
-  /* True if the argument is a record or union type.  */
-  bool struct_p;
-
   /* True if the argument is passed in a floating-point register, or
      would have been if we hadn't run out of registers.  */
   bool fpr_p;
@@ -3208,8 +3205,6 @@ mips_gen_conditional_trap (rtx *operands)
 void
 mips_expand_call (rtx result, rtx addr, rtx args_size, rtx aux, int sibcall_p)
 {
-  int i;
-
   if (!call_insn_operand (addr, VOIDmode))
     {
       /* When generating PIC, try to allow global functions to be
@@ -3226,16 +3221,6 @@ mips_expand_call (rtx result, rtx addr, rtx args_size, rtx aux, int sibcall_p)
       addr = force_reg (Pmode, addr);
     }
 
-  /* In order to pass small structures by value in registers
-     compatibly with the MIPS compiler, we need to shift the value
-     into the high part of the register.  Function_arg has encoded
-     a PARALLEL rtx, holding a vector of adjustments to be made
-     as the next_arg_reg variable, so we split up the insns,
-     and emit them separately.  */
-  if (aux != 0 && GET_CODE (aux) == PARALLEL)
-    for (i = 0; i < XVECLEN (aux, 0); i++)
-      emit_insn (XVECEXP (aux, 0, i));
-
   if (TARGET_MIPS16
       && mips16_hard_float
       && build_mips16_call_stub (result, addr, args_size,
@@ -3557,34 +3542,27 @@ mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
   bool even_reg_p;
   unsigned int num_words, max_regs;
 
-  info->struct_p = (type != 0
-                   && (TREE_CODE (type) == RECORD_TYPE
-                       || TREE_CODE (type) == UNION_TYPE
-                       || TREE_CODE (type) == QUAL_UNION_TYPE));
-
   /* Decide whether this argument should go in a floating-point register,
      assuming one is free.  Later code checks for availability.  */
 
-  info->fpr_p = false;
-  if (GET_MODE_CLASS (mode) == MODE_FLOAT
-      && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE)
-    {
-      switch (mips_abi)
-       {
-       case ABI_32:
-       case ABI_O64:
-         info->fpr_p = (!cum->gp_reg_found && cum->arg_number < 2);
-         break;
+  info->fpr_p = (GET_MODE_CLASS (mode) == MODE_FLOAT
+                && GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE);
 
-       case ABI_EABI:
-         info->fpr_p = true;
-         break;
+  if (info->fpr_p)
+    switch (mips_abi)
+      {
+      case ABI_32:
+      case ABI_O64:
+       info->fpr_p = (!cum->gp_reg_found
+                      && cum->arg_number < 2
+                      && (type == 0 || FLOAT_TYPE_P (type)));
+       break;
 
-       default:
-         info->fpr_p = named;
-         break;
-       }
-    }
+      case ABI_N32:
+      case ABI_64:
+       info->fpr_p = (named && (type == 0 || FLOAT_TYPE_P (type)));
+       break;
+      }
 
   /* Now decide whether the argument must go in an even-numbered register.  */
 
@@ -3648,36 +3626,6 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
 
   mips_arg_info (cum, mode, type, named, &info);
 
-  /* The following is a hack in order to pass 1 byte structures
-     the same way that the MIPS compiler does (namely by passing
-     the structure in the high byte or half word of the register).
-     This also makes varargs work.  If we have such a structure,
-     we save the adjustment RTL, and the call define expands will
-     emit them.  For the VOIDmode argument (argument after the
-     last real argument), pass back a parallel vector holding each
-     of the adjustments.  */
-
-  /* ??? This scheme requires everything smaller than the word size to
-     shifted to the left, but when TARGET_64BIT and ! TARGET_INT64,
-     that would mean every int needs to be shifted left, which is very
-     inefficient.  Let's not carry this compatibility to the 64 bit
-     calling convention for now.  */
-
-  if (info.struct_p
-      && info.reg_words == 1
-      && info.num_bytes < UNITS_PER_WORD
-      && !TARGET_64BIT
-      && mips_abi != ABI_EABI)
-    {
-      rtx amount = GEN_INT (BITS_PER_WORD - info.num_bytes * BITS_PER_UNIT);
-      rtx reg = gen_rtx_REG (word_mode, GP_ARG_FIRST + info.reg_offset);
-
-      if (TARGET_64BIT)
-       cum->adjust[cum->num_adjusts++] = PATTERN (gen_ashldi3 (reg, reg, amount));
-      else
-       cum->adjust[cum->num_adjusts++] = PATTERN (gen_ashlsi3 (reg, reg, amount));
-    }
-
   if (!info.fpr_p)
     cum->gp_reg_found = true;
 
@@ -3708,18 +3656,11 @@ function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
 
   /* We will be called with a mode of VOIDmode after the last argument
      has been seen.  Whatever we return will be passed to the call
-     insn.  If we need any shifts for small structures, return them in
-     a PARALLEL; in that case, stuff the mips16 fp_code in as the
-     mode.  Otherwise, if we need a mips16 fp_code, return a REG
-     with the code stored as the mode.  */
+     insn.  If we need a mips16 fp_code, return a REG with the code
+     stored as the mode.  */
   if (mode == VOIDmode)
     {
-      if (cum->num_adjusts > 0)
-       return gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
-                                gen_rtvec_v (cum->num_adjusts,
-                                             (rtx *) cum->adjust));
-
-      else if (TARGET_MIPS16 && cum->fp_code != 0)
+      if (TARGET_MIPS16 && cum->fp_code != 0)
        return gen_rtx_REG ((enum machine_mode) cum->fp_code, 0);
 
       else
@@ -3737,8 +3678,7 @@ function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
       && (mips_abi == ABI_N32 || mips_abi == ABI_64)
       && TYPE_SIZE_UNIT (type)
       && host_integerp (TYPE_SIZE_UNIT (type), 1)
-      && named
-      && mode != DFmode)
+      && named)
     {
       /* The Irix 6 n32/n64 ABIs say that if any 64 bit chunk of the
         structure contains a double in its entirety, then that 64 bit
@@ -3815,6 +3755,55 @@ function_arg_partial_nregs (const CUMULATIVE_ARGS *cum,
   mips_arg_info (cum, mode, type, named, &info);
   return info.stack_words > 0 ? info.reg_words : 0;
 }
+
+
+/* Return true if FUNCTION_ARG_PADDING (MODE, TYPE) should return
+   upward rather than downward.  In other words, return true if the
+   first byte of the stack slot has useful data, false if the last
+   byte does.  */
+
+bool
+mips_pad_arg_upward (enum machine_mode mode, tree type)
+{
+  /* On little-endian targets, the first byte of every stack argument
+     is passed in the first byte of the stack slot.  */
+  if (!BYTES_BIG_ENDIAN)
+    return true;
+
+  /* Otherwise, integral types are padded downward: the last byte of a
+     stack argument is passed in the last byte of the stack slot.  */
+  if (type != 0
+      ? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
+      : GET_MODE_CLASS (mode) == MODE_INT)
+    return false;
+
+  /* Other types are padded upward for o32, o64, n32 and n64.  */
+  if (mips_abi != ABI_EABI)
+    return true;
+
+  /* Arguments smaller than a stack slot are padded downward.  */
+  if (mode != BLKmode)
+    return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY);
+  else
+    return (int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT));
+}
+
+
+/* Likewise BLOCK_REG_PADDING (MODE, TYPE, ...).  Return !BYTES_BIG_ENDIAN
+   if the least significant byte of the register has useful data.  Return
+   the opposite if the most significant byte does.  */
+
+bool
+mips_pad_reg_upward (enum machine_mode mode, tree type)
+{
+  /* No shifting is required for floating-point arguments.  */
+  if (type != 0 ? FLOAT_TYPE_P (type) : GET_MODE_CLASS (mode) == MODE_FLOAT)
+    return !BYTES_BIG_ENDIAN;
+
+  /* Otherwise, apply the same padding to register arguments as we do
+     to stack arguments.  */
+  return mips_pad_arg_upward (mode, type);
+}
 \f
 int
 mips_setup_incoming_varargs (const CUMULATIVE_ARGS *cum,
@@ -6716,8 +6705,6 @@ mips_expand_prologue (void)
   tree fndecl = current_function_decl;
   tree fntype = TREE_TYPE (fndecl);
   tree fnargs = DECL_ARGUMENTS (fndecl);
-  rtx next_arg_reg;
-  int i;
   tree cur_arg;
   CUMULATIVE_ARGS args_so_far;
   rtx reg_18_save = NULL_RTX;
@@ -6757,39 +6744,6 @@ mips_expand_prologue (void)
       FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1);
     }
 
-  /* In order to pass small structures by value in registers compatibly with
-     the MIPS compiler, we need to shift the value into the high part of the
-     register.  Function_arg has encoded a PARALLEL rtx, holding a vector of
-     adjustments to be made as the next_arg_reg variable, so we split up the
-     insns, and emit them separately.  */
-
-  next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
-  if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
-    {
-      rtvec adjust = XVEC (next_arg_reg, 0);
-      int num = GET_NUM_ELEM (adjust);
-
-      for (i = 0; i < num; i++)
-       {
-         rtx insn, pattern;
-
-         pattern = RTVEC_ELT (adjust, i);
-         if (GET_CODE (pattern) != SET
-             || GET_CODE (SET_SRC (pattern)) != ASHIFT)
-           fatal_insn ("insn is not a shift", pattern);
-         PUT_CODE (SET_SRC (pattern), ASHIFTRT);
-
-         insn = emit_insn (pattern);
-
-         /* Global life information isn't valid at this point, so we
-            can't check whether these shifts are actually used.  Mark
-            them MAYBE_DEAD so that flow2 will remove them, and not
-            complain about dead code in the prologue.  */
-         REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
-                                              REG_NOTES (insn));
-       }
-    }
-
   tsize = compute_frame_size (get_frame_size ());
 
   /* If we are using the entry pseudo instruction, it will
index 38aa951..949fc74 100644 (file)
@@ -1399,9 +1399,8 @@ extern const struct mips_cpu_info *mips_tune_info;
        || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
 
 
-/* Force right-alignment for small varargs in 32 bit little_endian mode */
-
-#define PAD_VARARGS_DOWN (TARGET_64BIT ? BYTES_BIG_ENDIAN : !BYTES_BIG_ENDIAN)
+#define PAD_VARARGS_DOWN \
+  (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
 
 /* Arguments declared as 'char' or 'short' in a prototype should be
    passed as 'int's.  */
@@ -2295,15 +2294,6 @@ typedef struct mips_args {
 
   /* True if the function has a prototype.  */
   int prototype;
-
-  /* When a structure does not take up a full register, the argument
-     should sometimes be shifted left so that it occupies the high part
-     of the register.  These two fields describe an array of ashl
-     patterns for doing this.  See function_arg_advance, which creates
-     the shift patterns, and function_arg, which returns them when given
-     a VOIDmode argument.  */
-  unsigned int num_adjusts;
-  rtx adjust[BIGGEST_MAX_ARGS_IN_REGISTERS];
 } CUMULATIVE_ARGS;
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
@@ -2361,18 +2351,11 @@ typedef struct mips_args {
 #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED)         \
   function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED)
 
-#define FUNCTION_ARG_PADDING(MODE, TYPE)                               \
-  (! BYTES_BIG_ENDIAN                                                  \
-   ? upward                                                            \
-   : (((MODE) == BLKmode                                               \
-       ? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST                \
-         && int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT))\
-       : (GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY                      \
-         && (mips_abi == ABI_32                                        \
-             || mips_abi == ABI_O64                                    \
-             || mips_abi == ABI_EABI                                   \
-             || GET_MODE_CLASS (MODE) == MODE_INT)))                   \
-      ? downward : upward))
+#define FUNCTION_ARG_PADDING(MODE, TYPE)               \
+  (mips_pad_arg_upward (MODE, TYPE) ? upward : downward)
+
+#define BLOCK_REG_PADDING(MODE, TYPE, FIRST)           \
+  (mips_pad_reg_upward (MODE, TYPE) ? upward : downward)
 
 #define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED)             \
   (mips_abi == ABI_EABI && (NAMED)                                     \
index fd7c7f7..a17ace1 100644 (file)
@@ -4674,9 +4674,8 @@ assign_parms (tree fndecl)
 
              if (stack_parm == 0)
                {
-                 stack_parm
-                   = assign_stack_local (GET_MODE (entry_parm),
-                                         size_stored, 0);
+                 stack_parm = assign_stack_local (BLKmode, size_stored, 0);
+                 PUT_MODE (stack_parm, GET_MODE (entry_parm));
                  set_mem_attributes (stack_parm, parm, 1);
                }