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. */
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");
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);
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
{
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;
}
/* 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 ();
&& 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