summaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>1995-04-25 23:09:01 +0000
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>1995-04-25 23:09:01 +0000
commit121c11f94a9e0cabdab476d8074ff941ffdb8f0b (patch)
tree63648aa101e5be14d9b572542cac6a2ceb7e306a /gcc/expr.c
parent77b3577adeae9fcd64b3ef17d039448b9353fbdd (diff)
downloadgcc-121c11f94a9e0cabdab476d8074ff941ffdb8f0b.tar.gz
(expand_builtin_apply_args): If STACK_REGS is defined, generate USE
insns before the function body, thus showing which registers are filled with parameters. Reverse order of saving registers, more compact code for i387. (expand_builtin_apply): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@9462 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index c76feb01352..e9b20129cd0 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -8117,17 +8117,35 @@ expand_builtin_apply_args ()
if (struct_value_rtx)
size += GET_MODE_SIZE (Pmode);
- /* Save each register used in calling a function to the block. */
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ /* Save each register used in calling a function to the block.
+ Doing this in reverse order makes for much more compact code
+ for i386 and family. If we do this in reverse order, a simple
+ series of pops and stores will be generated. If we do this
+ in ascending order, the pops and stores will be littered with
+ stack swaps as well. Since the order is largely irrelevant for
+ all other architectures, we use the optimal order for the i386. */
+ for (regno = FIRST_PSEUDO_REGISTER; regno--;)
if ((mode = apply_args_mode[regno]) != VOIDmode)
{
+ rtx tem;
+
align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;
if (size % align != 0)
size = CEIL (size, align) * align;
+
+ tem = gen_rtx (REG, mode, INCOMING_REGNO (regno));
+
+#ifdef STACK_REGS
+ /* For reg-stack.c's stack register household.
+ Compare with a similar piece of code in function.c. */
+
+ emit_insn (gen_rtx (USE, mode, tem));
+#endif
+
emit_move_insn (change_address (registers, mode,
plus_constant (XEXP (registers, 0),
size)),
- gen_rtx (REG, mode, INCOMING_REGNO (regno)));
+ tem);
size += GET_MODE_SIZE (mode);
}
@@ -8206,8 +8224,10 @@ expand_builtin_apply (function, arguments, argsize)
size += GET_MODE_SIZE (Pmode);
/* Restore each of the registers previously saved. Make USE insns
- for each of these registers for use in making the call. */
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ for each of these registers for use in making the call.
+ Doing this in reverse order makes for much more compact code
+ for i386 and family. */
+ for (regno = FIRST_PSEUDO_REGISTER; regno--; )
if ((mode = apply_args_mode[regno]) != VOIDmode)
{
align = GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT;