OSDN Git Service

* config/sparc/sparc.md (save_register_windowdi): Add missing mode.
[pf3gnuchains/gcc-fork.git] / gcc / calls.c
index 3c4d13e..0d0c0f2 100644 (file)
@@ -832,10 +832,19 @@ store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals)
            < (unsigned int) MIN (BIGGEST_ALIGNMENT, BITS_PER_WORD)))
       {
        int bytes = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
-       int nregs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
        int endian_correction = 0;
 
-       args[i].n_aligned_regs = args[i].partial ? args[i].partial : nregs;
+       if (args[i].partial)
+         {
+           gcc_assert (args[i].partial % UNITS_PER_WORD == 0);
+           args[i].n_aligned_regs = args[i].partial / UNITS_PER_WORD;
+         }
+       else
+         {
+           args[i].n_aligned_regs
+             = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+         }
+
        args[i].aligned_regs = xmalloc (sizeof (rtx) * args[i].n_aligned_regs);
 
        /* Structures smaller than a word are normally aligned to the
@@ -973,7 +982,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
         args[i].reg is nonzero if all or part is passed in registers.
 
         args[i].partial is nonzero if part but not all is passed in registers,
-        and the exact value says how many words are passed in registers.
+        and the exact value says how many bytes are passed in registers.
 
         args[i].pass_on_stack is nonzero if the argument must at least be
         computed on the stack.  It may then be loaded back into registers
@@ -1079,8 +1088,8 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
 
       if (args[i].reg)
        args[i].partial
-         = FUNCTION_ARG_PARTIAL_NREGS (*args_so_far, mode, type,
-                                       argpos < n_named_args);
+         = targetm.calls.arg_partial_bytes (args_so_far, mode, type,
+                                            argpos < n_named_args);
 
       args[i].pass_on_stack = targetm.calls.must_pass_in_stack (mode, type);
 
@@ -1454,8 +1463,13 @@ load_register_parameters (struct arg_data *args, int num_actuals,
             we just use a normal move insn.  This value can be zero if the
             argument is a zero size structure with no fields.  */
          nregs = -1;
-         if (partial)
-           nregs = partial;
+         if (GET_CODE (reg) == PARALLEL)
+           ;
+         else if (partial)
+           {
+             gcc_assert (partial % UNITS_PER_WORD == 0);
+             nregs = partial / UNITS_PER_WORD;
+           }
          else if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode)
            {
              size = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
@@ -1554,8 +1568,8 @@ load_register_parameters (struct arg_data *args, int num_actuals,
            use_group_regs (call_fusage, reg);
          else if (nregs == -1)
            use_reg (call_fusage, reg);
-         else
-           use_regs (call_fusage, REGNO (reg), nregs == 0 ? 1 : nregs);
+         else if (nregs > 0)
+           use_regs (call_fusage, REGNO (reg), nregs);
        }
     }
 }
@@ -3286,7 +3300,6 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
   if (mem_value && struct_value == 0 && ! pcc_struct_value)
     {
       rtx addr = XEXP (mem_value, 0);
-      int partial;
       
       nargs++;
 
@@ -3300,8 +3313,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
       argvec[count].partial = 0;
 
       argvec[count].reg = FUNCTION_ARG (args_so_far, Pmode, NULL_TREE, 1);
-      partial = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, Pmode, NULL_TREE, 1);
-      gcc_assert (!partial);
+      gcc_assert (targetm.calls.arg_partial_bytes (&args_so_far, Pmode,
+                                                  NULL_TREE, 1) == 0);
 
       locate_and_pad_parm (Pmode, NULL_TREE,
 #ifdef STACK_PARMS_IN_REG_PARM_AREA
@@ -3387,7 +3400,7 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
       argvec[count].reg = FUNCTION_ARG (args_so_far, mode, NULL_TREE, 1);
 
       argvec[count].partial
-       = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode, NULL_TREE, 1);
+       = targetm.calls.arg_partial_bytes (&args_so_far, mode, NULL_TREE, 1);
 
       locate_and_pad_parm (mode, NULL_TREE,
 #ifdef STACK_PARMS_IN_REG_PARM_AREA
@@ -4097,20 +4110,11 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags,
        }
       else
        {
-         /* PUSH_ROUNDING has no effect on us, because
-            emit_push_insn for BLKmode is careful to avoid it.  */
-         if (reg && GET_CODE (reg) == PARALLEL)
-         {
-           /* Use the size of the elt to compute excess.  */
-           rtx elt = XEXP (XVECEXP (reg, 0, 0), 0);
-           excess = (arg->locate.size.constant
-                     - int_size_in_bytes (TREE_TYPE (pval))
-                     + partial * GET_MODE_SIZE (GET_MODE (elt)));
-         }
-         else
-           excess = (arg->locate.size.constant
-                     - int_size_in_bytes (TREE_TYPE (pval))
-                     + partial * UNITS_PER_WORD);
+         /* PUSH_ROUNDING has no effect on us, because emit_push_insn
+            for BLKmode is careful to avoid it.  */
+         excess = (arg->locate.size.constant
+                   - int_size_in_bytes (TREE_TYPE (pval))
+                   + partial);
          size_rtx = expand_expr (size_in_bytes (TREE_TYPE (pval)),
                                  NULL_RTX, TYPE_MODE (sizetype), 0);
        }