aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJim Wilson <wilson@gcc.gnu.org>1992-12-31 14:21:06 -0800
committerJim Wilson <wilson@gcc.gnu.org>1992-12-31 14:21:06 -0800
commit3412b298a26d6c8d2fd24d9875e37be0c8c4d136 (patch)
tree7928f4bcd8576f9705f2d7e7f5225b82db691a70 /gcc
parent6ffe0821bb193f71b3ef9ba8fa0272c9e61914bc (diff)
downloadgcc-3412b298a26d6c8d2fd24d9875e37be0c8c4d136.zip
gcc-3412b298a26d6c8d2fd24d9875e37be0c8c4d136.tar.gz
gcc-3412b298a26d6c8d2fd24d9875e37be0c8c4d136.tar.bz2
(assign_parms): Emit conversions into a sequence, and
then output the sequence after all parameters have been moved. From-SVN: r3025
Diffstat (limited to 'gcc')
-rw-r--r--gcc/function.c54
1 files changed, 39 insertions, 15 deletions
diff --git a/gcc/function.c b/gcc/function.c
index d5ea00b..70e04df 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -2607,6 +2607,7 @@ assign_parms (fndecl, second_time)
tree function_result_decl = 0;
int nparmregs = list_length (fnargs) + LAST_VIRTUAL_REGISTER + 1;
int varargs_setup = 0;
+ rtx conversion_insns = 0;
/* Nonzero if the last arg is named `__builtin_va_alist',
which is used on some machines for old-fashioned non-ANSI varargs.h;
@@ -3050,14 +3051,22 @@ assign_parms (fndecl, second_time)
register for a DFmode). In that case, moves are the only
thing valid, so we can't do a convert from there. This
occurs when the calling sequence allow such misaligned
- usages. */
- if (GET_CODE (entry_parm) == REG
- && REGNO (entry_parm) < FIRST_PSEUDO_REGISTER
- && ! HARD_REGNO_MODE_OK (REGNO (entry_parm),
- GET_MODE (entry_parm)))
- convert_move (parmreg, copy_to_reg (entry_parm), unsignedp);
- else
- convert_move (parmreg, validize_mem (entry_parm), unsignedp);
+ usages.
+
+ In addition, the conversion may involve a call, which could
+ clobber parameters which haven't been copied to pseudo
+ registers yet. Therefore, we must first copy the parm to
+ a pseudo reg here, and save the conversion until after all
+ parameters have been moved. */
+
+ rtx tempreg = gen_reg_rtx (GET_MODE (entry_parm));
+
+ emit_move_insn (tempreg, validize_mem (entry_parm));
+
+ push_to_sequence (conversion_insns);
+ convert_move (parmreg, tempreg);
+ conversion_insns = get_insns ();
+ end_sequence ();
}
else
emit_move_insn (parmreg, validize_mem (entry_parm));
@@ -3122,13 +3131,15 @@ assign_parms (fndecl, second_time)
if (passed_mode != nominal_mode)
{
/* Conversion is required. */
- if (GET_CODE (entry_parm) == REG
- && REGNO (entry_parm) < FIRST_PSEUDO_REGISTER
- && ! HARD_REGNO_MODE_OK (REGNO (entry_parm), passed_mode))
- entry_parm = copy_to_reg (entry_parm);
+ rtx tempreg = gen_reg_rtx (GET_MODE (entry_parm));
+
+ emit_move_insn (tempreg, validize_mem (entry_parm));
- entry_parm = convert_to_mode (nominal_mode, entry_parm,
+ push_to_sequence (conversion_insns);
+ entry_parm = convert_to_mode (nominal_mode, tempreg,
TREE_UNSIGNED (TREE_TYPE (parm)));
+ conversion_insns = get_insns ();
+ end_sequence ();
}
if (entry_parm != stack_parm)
@@ -3143,8 +3154,17 @@ assign_parms (fndecl, second_time)
MEM_IN_STRUCT_P (stack_parm) = aggregate;
}
- emit_move_insn (validize_mem (stack_parm),
- validize_mem (entry_parm));
+ if (passed_mode != nominal_mode)
+ {
+ push_to_sequence (conversion_insns);
+ emit_move_insn (validize_mem (stack_parm),
+ validize_mem (entry_parm));
+ conversion_insns = get_insns ();
+ end_sequence ();
+ }
+ else
+ emit_move_insn (validize_mem (stack_parm),
+ validize_mem (entry_parm));
}
DECL_RTL (parm) = stack_parm;
@@ -3162,6 +3182,10 @@ assign_parms (fndecl, second_time)
RTX_UNCHANGING_P (DECL_RTL (parm)) = 1;
}
+ /* Output all parameter conversion instructions (possibly including calls)
+ now that all parameters have been copied out of hard registers. */
+ emit_insns (conversion_insns);
+
max_parm_reg = max_reg_num ();
last_parm_insn = get_last_insn ();