Ignore:
Timestamp:
Apr 28, 2004, 6:58:06 AM (21 years ago)
Author:
bird
Message:

#1040: Joined the GCC 3.3.3 with the trunk.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gcc/gcc/calls.c

    • Property cvs2svn:cvs-rev changed from 1.2 to 1.3
    r1393 r1394  
    11/* Convert function calls to rtl insns, for GNU C compiler.
    22   Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
    3    1999, 2000, 2001 Free Software Foundation, Inc.
     3   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
    44
    55This file is part of GCC.
     
    3434#include "timevar.h"
    3535#include "sbitmap.h"
     36#include "langhooks.h"
     37#include "target.h"
     38#include "except.h"
    3639
    3740#if !defined FUNCTION_OK_FOR_SIBCALL
     
    9295     Also 0 if not passed in registers.  */
    9396  int partial;
    94   /* Non-zero if argument must be passed on stack.
     97  /* Nonzero if argument must be passed on stack.
    9598     Note that some arguments may be passed on the stack
    9699     even though pass_on_stack is zero, just because FUNCTION_ARG says so.
     
    127130};
    128131
    129 /* A vector of one char per byte of stack space.  A byte if non-zero if
     132/* A vector of one char per byte of stack space.  A byte if nonzero if
    130133   the corresponding stack location has been used.
    131134   This vector is used to prevent a function call within an argument from
     
    226229static int combine_pending_stack_adjustment_and_call
    227230                                                PARAMS ((int, struct args_size *, int));
     231static tree fix_unsafe_tree             PARAMS ((tree));
    228232
    229233#ifdef REG_PARM_STACK_SPACE
     
    617621    REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, const0_rtx,
    618622                                               REG_NOTES (call_insn));
     623  else
     624    note_eh_region_may_contain_throw ();
    619625
    620626  if (ecf_flags & ECF_NORETURN)
     
    637643     if the context of the call as a whole permits.  */
    638644  inhibit_defer_pop = old_inhibit_defer_pop;
     645
     646  /* Don't bother cleaning up after a noreturn function.  */
     647  if (ecf_flags & (ECF_NORETURN | ECF_LONGJMP))
     648    return;
    639649
    640650  if (n_popped > 0)
     
    802812}
    803813
     814/* Return true when exp contains alloca call.  */
     815bool
     816alloca_call_p (exp)
     817     tree exp;
     818{
     819  if (TREE_CODE (exp) == CALL_EXPR
     820      && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
     821      && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
     822          == FUNCTION_DECL)
     823      && (special_function_p (TREE_OPERAND (TREE_OPERAND (exp, 0), 0),
     824                              0) & ECF_MAY_BE_ALLOCA))
     825    return true;
     826  return false;
     827}
     828
    804829/* Detect flags (function attributes) from the function decl or type node.  */
    805830
     
    825850      if (TREE_NOTHROW (exp))
    826851        flags |= ECF_NOTHROW;
     852
     853      if (TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp))
     854        flags |= ECF_LIBCALL_BLOCK;
    827855    }
    828856
    829857  if (TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp))
    830     flags |= ECF_CONST | ECF_LIBCALL_BLOCK;
     858    flags |= ECF_CONST;
    831859
    832860  if (TREE_THIS_VOLATILE (exp))
     
    878906            emit_queue ();
    879907          }
     908
     909        /* If the value is a non-legitimate constant, force it into a
     910           pseudo now.  TLS symbols sometimes need a call to resolve.  */
     911        if (CONSTANT_P (args[i].value)
     912            && !LEGITIMATE_CONSTANT_P (args[i].value))
     913          args[i].value = force_reg (args[i].mode, args[i].value);
    880914
    881915        /* If we are to promote the function arg to a wider mode,
     
    9701004        {
    9711005          save_area = assign_stack_temp (BLKmode, num_to_save, 0);
    972           /* Cannot use emit_block_move here because it can be done by a
    973              library call which in turn gets into this place again and deadly
    974              infinite recursion happens.  */
    975           move_by_pieces (validize_mem (save_area), stack_area, num_to_save,
    976                           PARM_BOUNDARY);
     1006          emit_block_move (validize_mem (save_area), stack_area,
     1007                           GEN_INT (num_to_save), BLOCK_OP_CALL_PARM);
    9771008        }
    9781009      else
     
    10111042    emit_move_insn (stack_area, save_area);
    10121043  else
    1013     /* Cannot use emit_block_move here because it can be done by a library
    1014        call which in turn gets into this place again and deadly infinite
    1015        recursion happens.  */
    1016     move_by_pieces (stack_area, validize_mem (save_area),
    1017                     high_to_save - low_to_save + 1, PARM_BOUNDARY);
     1044    emit_block_move (stack_area, validize_mem (save_area),
     1045                     GEN_INT (high_to_save - low_to_save + 1),
     1046                     BLOCK_OP_CALL_PARM);
    10181047}
    10191048#endif /* REG_PARM_STACK_SPACE */
     
    10561085           calculating the bit offset.  */
    10571086        if (BYTES_BIG_ENDIAN
    1058             && !FUNCTION_ARG_REG_LITTLE_ENDIAN
    10591087            && bytes < UNITS_PER_WORD)
    10601088          big_endian_correction = (BITS_PER_WORD  - (bytes * BITS_PER_UNIT));
     
    15421570                  = gen_lowpart_SUBREG (mode, args[i].value);
    15431571                SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1;
    1544                 SUBREG_PROMOTED_UNSIGNED_P (args[i].initial_value)
    1545                   = args[i].unsignedp;
     1572                SUBREG_PROMOTED_UNSIGNED_SET (args[i].initial_value,
     1573                  args[i].unsignedp);
    15461574              }
    15471575#endif
     
    16481676          addr = plus_constant (addr, arg_offset);
    16491677          args[i].stack = gen_rtx_MEM (args[i].mode, addr);
     1678          set_mem_align (args[i].stack, PARM_BOUNDARY);
    16501679          set_mem_attributes (args[i].stack,
    16511680                              TREE_TYPE (args[i].tree_value), 1);
     
    16581687          addr = plus_constant (addr, arg_offset);
    16591688          args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr);
     1689          set_mem_align (args[i].stack_slot, PARM_BOUNDARY);
    16601690          set_mem_attributes (args[i].stack_slot,
    16611691                              TREE_TYPE (args[i].tree_value), 1);
     
    16771707   FNDECL will be NULL_TREE.
    16781708
    1679    EXP is the CALL_EXPR for this call.  */
     1709   ADDR is the operand 0 of CALL_EXPR for this call.  */
    16801710
    16811711static rtx
    1682 rtx_for_function_call (fndecl, exp)
     1712rtx_for_function_call (fndecl, addr)
    16831713     tree fndecl;
    1684      tree exp;
     1714     tree addr;
    16851715{
    16861716  rtx funexp;
     
    17061736      push_temp_slots ();
    17071737      funaddr = funexp
    1708         = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0);
     1738        = expand_expr (addr, NULL_RTX, VOIDmode, 0);
    17091739      pop_temp_slots ();        /* FUNEXP can't be BLKmode.  */
    17101740      emit_queue ();
     
    18841914                  seq = get_insns ();
    18851915                  end_sequence ();
    1886                   emit_insns_before (seq, first_insn);
     1916                  emit_insn_before (seq, first_insn);
    18871917                  emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
    18881918                }
     
    19071937      warning ("called from here");
    19081938    }
    1909   mark_addressable (fndecl);
     1939  (*lang_hooks.mark_addressable) (fndecl);
    19101940  return (rtx) (size_t) - 1;
    19111941}
     
    19732003   we already clobbered by tail call arguments (as noted in stored_args_map
    19742004   bitmap).
    1975    Return non-zero if X expression dereferences such argument slots,
     2005   Return nonzero if X expression dereferences such argument slots,
    19762006   zero otherwise.  */
    19772007
     
    20362066   we already clobbered by tail call arguments (as noted in stored_args_map
    20372067   bitmap).  Add stack slots for ARG to stored_args_map bitmap afterwards.
    2038    Return non-zero if sequence after INSN dereferences such argument slots,
     2068   Return nonzero if sequence after INSN dereferences such argument slots,
    20392069   zero otherwise.  */
    20402070
     
    22072237  rtx call_fusage;
    22082238  tree p = TREE_OPERAND (exp, 0);
     2239  tree addr = TREE_OPERAND (exp, 0);
    22092240  int i;
    22102241  /* The alignment of the stack, in bits.  */
     
    22422273              warning ("called from here");
    22432274            }
    2244           mark_addressable (fndecl);
     2275          (*lang_hooks.mark_addressable) (fndecl);
    22452276        }
    22462277
     
    22882319               used.  */
    22892320            if (! TREE_ADDRESSABLE (fndecl))
    2290               mark_addressable (fndecl);
     2321              (*lang_hooks.mark_addressable) (fndecl);
    22912322            is_integrable = 0;
    22922323          }
     
    23282359
    23292360  /* Operand 0 is a pointer-to-function; get the type of the function.  */
    2330   funtype = TREE_TYPE (TREE_OPERAND (exp, 0));
     2361  funtype = TREE_TYPE (addr);
    23312362  if (! POINTER_TYPE_P (funtype))
    23322363    abort ();
     
    24652496  /* Tail recursion fails, when we are not dealing with recursive calls.  */
    24662497  if (!try_tail_recursion
    2467       || TREE_CODE (TREE_OPERAND (exp, 0)) != ADDR_EXPR
    2468       || TREE_OPERAND (TREE_OPERAND (exp, 0), 0) != current_function_decl)
     2498      || TREE_CODE (addr) != ADDR_EXPR
     2499      || TREE_OPERAND (addr, 0) != current_function_decl)
    24692500    try_tail_recursion = 0;
    24702501
     
    24902521         before the sibcall_epilogue.  */
    24912522      || fndecl == NULL_TREE
    2492       || (flags & (ECF_RETURNS_TWICE | ECF_LONGJMP))
    2493       || TREE_THIS_VOLATILE (fndecl)
     2523      || (flags & (ECF_RETURNS_TWICE | ECF_LONGJMP | ECF_NORETURN))
    24942524      || !FUNCTION_OK_FOR_SIBCALL (fndecl)
    24952525      /* If this function requires more stack slots than the current
     
    24982528      /* If the callee pops its own arguments, then it must pop exactly
    24992529         the same number of arguments as the current function.  */
    2500       || RETURN_POPS_ARGS (fndecl, funtype, args_size.constant)
    2501          != RETURN_POPS_ARGS (current_function_decl,
    2502                               TREE_TYPE (current_function_decl),
    2503                               current_function_args_size))
    2504   try_tail_call = 0;
     2530      || (RETURN_POPS_ARGS (fndecl, funtype, args_size.constant)
     2531          != RETURN_POPS_ARGS (current_function_decl,
     2532                               TREE_TYPE (current_function_decl),
     2533                               current_function_args_size))
     2534      || !(*lang_hooks.decls.ok_for_sibcall) (fndecl))
     2535    try_tail_call = 0;
    25052536
    25062537  if (try_tail_call || try_tail_recursion)
     
    25472578      /* Do the same for the function address if it is an expression. */
    25482579      if (!fndecl)
    2549         TREE_OPERAND (exp, 0) = fix_unsafe_tree (TREE_OPERAND (exp, 0));
     2580        addr = fix_unsafe_tree (addr);
    25502581      /* Expanding one of those dangerous arguments could have added
    25512582         cleanups, but otherwise give it a whirl.  */
     
    29412972      NO_DEFER_POP;
    29422973
    2943       funexp = rtx_for_function_call (fndecl, exp);
     2974      funexp = rtx_for_function_call (fndecl, addr);
    29442975
    29452976      /* Figure out the register where the value, if any, will come back.  */
     
    30773108      /* Verify that we've deallocated all the stack we used.  */
    30783109      if (pass
     3110          && ! (flags & (ECF_NORETURN | ECF_LONGJMP))
    30793111          && old_stack_allocated != stack_pointer_delta - pending_stack_adjust)
    30803112        abort ();
     
    30923124              insns = get_insns ();
    30933125              end_sequence ();
    3094               emit_insns (insns);
     3126              emit_insn (insns);
    30953127            }
    30963128          else
     
    31463178          insns = get_insns ();
    31473179          end_sequence ();
    3148           emit_insns (insns);
     3180          emit_insn (insns);
    31493181          valreg = temp;
    31503182        }
     
    31703202
    31713203          emit_barrier_after (last);
     3204
     3205          /* Stack adjustments after a noreturn call are dead code.  */
     3206          stack_pointer_delta = old_stack_allocated;
     3207          pending_stack_adjust = 0;
    31723208        }
    31733209
     
    32913327          target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset);
    32923328          SUBREG_PROMOTED_VAR_P (target) = 1;
    3293           SUBREG_PROMOTED_UNSIGNED_P (target) = unsignedp;
     3329          SUBREG_PROMOTED_UNSIGNED_SET (target, unsignedp);
    32943330        }
    32953331#endif
     
    33303366                  emit_move_insn (stack_area, args[i].save_area);
    33313367                else
    3332                   emit_block_move (stack_area,
    3333                                    validize_mem (args[i].save_area),
    3334                                    GEN_INT (args[i].size.constant));
     3368                  emit_block_move (stack_area, args[i].save_area,
     3369                                   GEN_INT (args[i].size.constant),
     3370                                   BLOCK_OP_CALL_PARM);
    33353371              }
    33363372
     
    34333469    }
    34343470  else
    3435     emit_insns (normal_call_insns);
     3471    emit_insn (normal_call_insns);
    34363472
    34373473  currently_expanding_call--;
     
    34983534  int needed;
    34993535  rtx before_call;
     3536  tree tfom;                    /* type_for_mode (outmode, 0) */
    35003537
    35013538#ifdef REG_PARM_STACK_SPACE
     
    35593596  /* If this kind of value comes back in memory,
    35603597     decide where in memory it should come back.  */
    3561   if (outmode != VOIDmode && aggregate_value_p (type_for_mode (outmode, 0)))
    3562     {
     3598  if (outmode != VOIDmode)
     3599    {
     3600      tfom = (*lang_hooks.types.type_for_mode) (outmode, 0);
     3601      if (aggregate_value_p (tfom))   
     3602        {
    35633603#ifdef PCC_STATIC_STRUCT_RETURN
    3564       rtx pointer_reg
    3565         = hard_function_value (build_pointer_type (type_for_mode (outmode, 0)),
    3566                                0, 0);
    3567       mem_value = gen_rtx_MEM (outmode, pointer_reg);
    3568       pcc_struct_value = 1;
    3569       if (value == 0)
    3570         value = gen_reg_rtx (outmode);
     3604          rtx pointer_reg
     3605            = hard_function_value (build_pointer_type (tfom), 0, 0);
     3606          mem_value = gen_rtx_MEM (outmode, pointer_reg);
     3607          pcc_struct_value = 1;
     3608          if (value == 0)
     3609            value = gen_reg_rtx (outmode);
    35713610#else /* not PCC_STATIC_STRUCT_RETURN */
    3572       struct_value_size = GET_MODE_SIZE (outmode);
    3573       if (value != 0 && GET_CODE (value) == MEM)
    3574         mem_value = value;
    3575       else
    3576         mem_value = assign_temp (type_for_mode (outmode, 0), 0, 1, 1);
    3577 #endif
    3578 
    3579       /* This call returns a big structure.  */
    3580       flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
    3581     }
     3611          struct_value_size = GET_MODE_SIZE (outmode);
     3612          if (value != 0 && GET_CODE (value) == MEM)
     3613            mem_value = value;
     3614          else
     3615            mem_value = assign_temp (tfom, 0, 1, 1);
     3616#endif
     3617          /* This call returns a big structure.  */
     3618          flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
     3619        }
     3620    }
     3621  else
     3622    tfom = void_type_node;
    35823623
    35833624  /* ??? Unfinished: must pass the memory address as an argument.  */
     
    36873728#endif
    36883729            ;
     3730
     3731          /* loop.c won't look at CALL_INSN_FUNCTION_USAGE of const/pure
     3732             functions, so we have to pretend this isn't such a function.  */
     3733          if (flags & ECF_LIBCALL_BLOCK)
     3734            {
     3735              rtx insns = get_insns ();
     3736              end_sequence ();
     3737              emit_insn (insns);
     3738            }
     3739          flags &= ~(ECF_CONST | ECF_PURE | ECF_LIBCALL_BLOCK);
    36893740
    36903741          /* If this was a CONST function, it is now PURE since
     
    37003751          else if (must_copy)
    37013752            {
    3702               slot = assign_temp (type_for_mode (mode, 0), 0, 1, 1);
     3753              slot = assign_temp ((*lang_hooks.types.type_for_mode) (mode, 0),
     3754                                  0, 1, 1);
    37033755              emit_move_insn (slot, val);
    37043756            }
    37053757          else
    37063758            {
    3707               tree type = type_for_mode (mode, 0);
     3759              tree type = (*lang_hooks.types.type_for_mode) (mode, 0);
    37083760
    37093761              slot = gen_rtx_MEM (mode,
     
    39153967              save_area = assign_stack_temp (BLKmode, num_to_save, 0);
    39163968              set_mem_align (save_area, PARM_BOUNDARY);
    3917               emit_block_move (validize_mem (save_area), stack_area,
    3918                                GEN_INT (num_to_save));
     3969              emit_block_move (save_area, stack_area, GEN_INT (num_to_save),
     3970                               BLOCK_OP_CALL_PARM);
    39193971            }
    39203972          else
     
    39784030                        plus_constant (argblock,
    39794031                                       argvec[argnum].offset.constant)));
    3980                   argvec[argnum].save_area = gen_reg_rtx (save_mode);
    3981 
    3982                   emit_move_insn (argvec[argnum].save_area, stack_area);
     4032                  if (save_mode == BLKmode)
     4033                    {
     4034                      argvec[argnum].save_area
     4035                        = assign_stack_temp (BLKmode,
     4036                                             argvec[argnum].size.constant, 0);
     4037
     4038                      emit_block_move (validize_mem (argvec[argnum].save_area),
     4039                                       stack_area,
     4040                                       GEN_INT (argvec[argnum].size.constant),
     4041                                       BLOCK_OP_CALL_PARM);
     4042                    }
     4043                  else
     4044                    {
     4045                      argvec[argnum].save_area = gen_reg_rtx (save_mode);
     4046
     4047                      emit_move_insn (argvec[argnum].save_area, stack_area);
     4048                    }
    39834049                }
    39844050            }
    39854051
    3986           emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0,
    3987                           argblock, GEN_INT (argvec[argnum].offset.constant),
     4052          emit_push_insn (val, mode, NULL_TREE, NULL_RTX, PARM_BOUNDARY,
     4053                          partial, reg, 0, argblock,
     4054                          GEN_INT (argvec[argnum].offset.constant),
    39884055                          reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
    39894056
     
    40724139  emit_call_1 (fun,
    40734140               get_identifier (XSTR (orgfun, 0)),
    4074                build_function_type (outmode == VOIDmode ? void_type_node
    4075                                     : type_for_mode (outmode, 0), NULL_TREE),
     4141               build_function_type (tfom, NULL_TREE),
    40764142               original_args_size.constant, args_size.constant,
    40774143               struct_value_size,
     
    41134179      rtx insns;
    41144180
    4115       if (valreg == 0 || GET_CODE (valreg) == PARALLEL)
     4181      if (valreg == 0)
    41164182        {
    41174183          insns = get_insns ();
    41184184          end_sequence ();
    4119           emit_insns (insns);
     4185          emit_insn (insns);
    41204186        }
    41214187      else
    41224188        {
    41234189          rtx note = 0;
    4124           rtx temp = gen_reg_rtx (GET_MODE (valreg));
     4190          rtx temp;
    41254191          int i;
     4192
     4193          if (GET_CODE (valreg) == PARALLEL)
     4194            {
     4195              temp = gen_reg_rtx (outmode);
     4196              emit_group_store (temp, valreg, outmode);
     4197              valreg = temp;
     4198            }
     4199
     4200          temp = gen_reg_rtx (GET_MODE (valreg));
    41264201
    41274202          /* Construct an "equal form" for the value which mentions all the
     
    41584233            emit_move_insn (value, mem_value);
    41594234        }
     4235      else if (GET_CODE (valreg) == PARALLEL)
     4236        {
     4237          if (value == 0)
     4238            value = gen_reg_rtx (outmode);
     4239          emit_group_store (value, valreg, outmode);
     4240        }
    41604241      else if (value != 0)
    4161         emit_move_insn (value, hard_libcall_value (outmode));
     4242        emit_move_insn (value, valreg);
    41624243      else
    4163         value = hard_libcall_value (outmode);
     4244        value = valreg;
    41644245    }
    41654246
     
    41874268            emit_move_insn (stack_area, save_area);
    41884269          else
    4189             emit_block_move (stack_area, validize_mem (save_area),
    4190                              GEN_INT (high_to_save - low_to_save + 1));
     4270            emit_block_move (stack_area, save_area,
     4271                             GEN_INT (high_to_save - low_to_save + 1),
     4272                             BLOCK_OP_CALL_PARM);
    41914273        }
    41924274#endif
     
    42044286                                             argvec[count].offset.constant)));
    42054287
    4206             emit_move_insn (stack_area, argvec[count].save_area);
     4288            if (save_mode == BLKmode)
     4289              emit_block_move (stack_area,
     4290                               validize_mem (argvec[count].save_area),
     4291                               GEN_INT (argvec[count].size.constant),
     4292                               BLOCK_OP_CALL_PARM);
     4293            else
     4294              emit_move_insn (stack_area, argvec[count].save_area);
    42074295          }
    42084296
     
    42934381   FNDECL is the declaration of the function we are calling.
    42944382
    4295    Return non-zero if this arg should cause sibcall failure,
     4383   Return nonzero if this arg should cause sibcall failure,
    42964384   zero otherwise.  */
    42974385
     
    43014389     rtx argblock;
    43024390     int flags;
    4303      int variable_size;
     4391     int variable_size ATTRIBUTE_UNUSED;
    43044392     int reg_parm_stack_space;
    43054393{
     
    43684456                  preserve_temp_slots (arg->save_area);
    43694457                  emit_block_move (validize_mem (arg->save_area), stack_area,
    4370                                    expr_size (arg->tree_value));
     4458                                   expr_size (arg->tree_value),
     4459                                   BLOCK_OP_CALL_PARM);
    43714460                }
    43724461              else
     
    43764465                }
    43774466            }
    4378 
    4379           /* Now that we have saved any slots that will be overwritten
    4380              by this store, mark all slots this store will use.  We
    4381              must do this before we actually expand the argument since
    4382              the expansion itself may trigger library calls which might
    4383              need to use the same stack slot. We only do it if we can't
    4384              pass all arguments to a library call in registers.  */
    4385           if (arg->partial)
    4386             {
    4387               for (i = lower_bound; i < upper_bound; i++)
    4388                 stack_usage_map[i] = 1;
    4389 
    4390               /* Set it so that we don't do it again.  */
    4391               variable_size = 1;
    4392             }
    43934467        }
    43944468    }
     
    44444518                                 || TYPE_MODE (TREE_TYPE (pval)) != arg->mode)
    44454519                                ? NULL_RTX : arg->stack,
    4446                                 VOIDmode, 0);
     4520                                VOIDmode, EXPAND_STACK_PARM);
    44474521
    44484522      /* If we are promoting object (or for any other reason) the mode
     
    44974571      /* This isn't already where we want it on the stack, so put it there.
    44984572         This can either be done with push or copy insns.  */
    4499       emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX, 0,
    4500                       partial, reg, used - size, argblock,
     4573      emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), NULL_RTX,
     4574                      PARM_BOUNDARY, partial, reg, used - size, argblock,
    45014575                      ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
    45024576                      ARGS_SIZE_RTX (arg->alignment_pad));
     
    45114585      /* BLKmode, at least partly to be pushed.  */
    45124586
     4587      unsigned int parm_align;
    45134588      int excess;
    45144589      rtx size_rtx;
     
    45344609          size_rtx = expand_expr (size_in_bytes (TREE_TYPE (pval)),
    45354610                                  NULL_RTX, TYPE_MODE (sizetype), 0);
     4611        }
     4612
     4613      /* Some types will require stricter alignment, which will be
     4614         provided for elsewhere in argument layout.  */
     4615      parm_align = MAX (PARM_BOUNDARY, TYPE_ALIGN (TREE_TYPE (pval)));
     4616
     4617      /* When an argument is padded down, the block is aligned to
     4618         PARM_BOUNDARY, but the actual argument isn't.  */
     4619      if (FUNCTION_ARG_PADDING (arg->mode, TREE_TYPE (pval)) == downward)
     4620        {
     4621          if (arg->size.var)
     4622            parm_align = BITS_PER_UNIT;
     4623          else if (excess)
     4624            {
     4625              unsigned int excess_align = (excess & -excess) * BITS_PER_UNIT;
     4626              parm_align = MIN (parm_align, excess_align);
     4627            }
    45364628        }
    45374629
     
    45694661        }
    45704662
    4571       /* Special handling is required if part of the parameter lies in the
    4572          register parameter area.  The argument may be copied into the stack
    4573          slot using memcpy(), but the original contents of the register
    4574          parameter area will be restored after the memcpy() call.
    4575 
    4576          To ensure that the part that lies in the register parameter area
    4577          is copied correctly, we emit a separate push for that part.  This
    4578          push should be small enough to avoid a call to memcpy().  */
    4579 #ifndef STACK_PARMS_IN_REG_PARM_AREA
    4580       if (arg->reg && arg->pass_on_stack)
    4581 #else
    4582       if (1)
    4583 #endif
    4584         {
    4585           if (arg->offset.constant < reg_parm_stack_space && arg->offset.var)
    4586             error ("variable offset is passed partially in stack and in reg");
    4587           else if (arg->offset.constant < reg_parm_stack_space && arg->size.var)
    4588             error ("variable size is passed partially in stack and in reg");
    4589           else if (arg->offset.constant < reg_parm_stack_space
    4590               && ((arg->offset.constant + arg->size.constant)
    4591                    > reg_parm_stack_space))
    4592           {
    4593             rtx size_rtx1 = GEN_INT (reg_parm_stack_space - arg->offset.constant);
    4594             emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx1,
    4595                             TYPE_ALIGN (TREE_TYPE (pval)), partial, reg,
    4596                             excess, argblock, ARGS_SIZE_RTX (arg->offset),
    4597                             reg_parm_stack_space,
    4598                             ARGS_SIZE_RTX (arg->alignment_pad));
    4599           }
    4600         }
    4601        
    4602 
    46034663      emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
    4604                       TYPE_ALIGN (TREE_TYPE (pval)), partial, reg, excess,
    4605                       argblock, ARGS_SIZE_RTX (arg->offset),
    4606                       reg_parm_stack_space,
     4664                      parm_align, partial, reg, excess, argblock,
     4665                      ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
    46074666                      ARGS_SIZE_RTX (arg->alignment_pad));
    46084667
     
    46194678    }
    46204679
     4680  /* Mark all slots this store used.  */
    46214681  if (ACCUMULATE_OUTGOING_ARGS && !(flags & ECF_SIBCALL)
    46224682      && argblock && ! variable_size && arg->stack)
Note: See TracChangeset for help on using the changeset viewer.