OSDN Git Service

2004-11-01 Andrew Pinski <pinskia@physics.uc.edu>
[pf3gnuchains/gcc-fork.git] / gcc / function.c
index 611589d..82776e7 100644 (file)
@@ -287,8 +287,6 @@ pop_function_context_from (tree context ATTRIBUTE_UNUSED)
   current_function_decl = p->decl;
   reg_renumber = 0;
 
-  restore_emit_status (p);
-
   lang_hooks.function.leave_nested (p);
 
   /* Reset variables that have known state during rtx generation.  */
@@ -535,7 +533,6 @@ insert_slot_to_list (struct temp_slot *temp, struct temp_slot **list)
 static struct temp_slot **
 temp_slots_at_level (int level)
 {
-  level++;
 
   if (!used_temp_slots)
     VARRAY_GENERIC_PTR_INIT (used_temp_slots, 3, "used_temp_slots");
@@ -1346,10 +1343,20 @@ instantiate_decl (rtx x, HOST_WIDE_INT size, int valid_only)
   enum machine_mode mode;
   rtx addr;
 
+  if (x == 0)
+    return;
+
+  /* If this is a CONCAT, recurse for the pieces.  */
+  if (GET_CODE (x) == CONCAT)
+    {
+      instantiate_decl (XEXP (x, 0), size / 2, valid_only);
+      instantiate_decl (XEXP (x, 1), size / 2, valid_only);
+      return;
+    }
+
   /* If this is not a MEM, no need to do anything.  Similarly if the
      address is a constant or a register that is not a virtual register.  */
-
-  if (x == 0 || !MEM_P (x))
+  if (!MEM_P (x))
     return;
 
   addr = XEXP (x, 0);
@@ -2513,8 +2520,12 @@ assign_parm_setup_block_p (struct assign_parm_data_one *data)
     return true;
 
 #ifdef BLOCK_REG_PADDING
-  if (data->locate.where_pad == (BYTES_BIG_ENDIAN ? upward : downward)
-      && GET_MODE_SIZE (data->promoted_mode) < UNITS_PER_WORD)
+  /* Only assign_parm_setup_block knows how to deal with register arguments
+     that are padded at the least significant end.  */
+  if (REG_P (data->entry_parm)
+      && GET_MODE_SIZE (data->promoted_mode) < UNITS_PER_WORD
+      && (BLOCK_REG_PADDING (data->passed_mode, data->passed_type, 1)
+         == (BYTES_BIG_ENDIAN ? upward : downward)))
     return true;
 #endif
 
@@ -2539,8 +2550,28 @@ assign_parm_setup_block (tree parm, struct assign_parm_data_one *data)
     {
       rtx parmreg = gen_reg_rtx (data->nominal_mode);
 
-      emit_group_store (parmreg, entry_parm, data->nominal_type,
-                       int_size_in_bytes (data->nominal_type));
+      /* For values returned in multiple registers, handle possible
+        incompatible calls to emit_group_store.
+
+        For example, the following would be invalid, and would have to
+        be fixed by the conditional below:
+
+          emit_group_store ((reg:SF), (parallel:DF))
+          emit_group_store ((reg:SI), (parallel:DI))
+
+        An example of this are doubles in e500 v2:
+          (parallel:DF (expr_list (reg:SI) (const_int 0))
+                       (expr_list (reg:SI) (const_int 4))).  */
+      if (data->nominal_mode != data->passed_mode)
+       {
+         rtx t = gen_reg_rtx (GET_MODE (entry_parm));
+         emit_group_store (t, entry_parm, NULL_TREE,
+                           GET_MODE_SIZE (GET_MODE (entry_parm)));
+         convert_move (parmreg, t, 0);
+       }
+      else
+       emit_group_store (parmreg, entry_parm, data->nominal_type,
+                         int_size_in_bytes (data->nominal_type));
       SET_DECL_RTL (parm, parmreg);
       return;
     }
@@ -2719,7 +2750,7 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
 
       /* TREE_USED gets set erroneously during expand_assignment.  */
       save_tree_used = TREE_USED (parm);
-      expand_assignment (parm, make_tree (data->nominal_type, tempreg), 0);
+      expand_assignment (parm, make_tree (data->nominal_type, tempreg));
       TREE_USED (parm) = save_tree_used;
       all->conversion_insns = get_insns ();
       end_sequence ();
@@ -3798,10 +3829,6 @@ allocate_struct_function (tree fndecl)
        && TYPE_ARG_TYPES (fntype) != 0
        && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
           != void_type_node));
-
-  /* Assume all registers in stdarg functions need to be saved.  */
-  cfun->va_list_gpr_size = VA_LIST_MAX_GPR_SIZE;
-  cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE;
 }
 
 /* Reset cfun, and other non-struct-function variables to defaults as