aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/config/alpha/alpha.c4
-rw-r--r--gcc/config/arc/arc.c6
-rw-r--r--gcc/config/i960/i960.c5
-rw-r--r--gcc/config/m32r/m32r.c5
-rw-r--r--gcc/config/m88k/m88k.c5
-rw-r--r--gcc/config/mips/mips.c2
-rw-r--r--gcc/config/pa/pa.c2
-rw-r--r--gcc/config/romp/romp.h6
-rw-r--r--gcc/config/rs6000/rs6000.c6
-rw-r--r--gcc/config/sh/sh.c6
-rw-r--r--gcc/expr.c45
-rw-r--r--gcc/expr.h4
-rw-r--r--gcc/function.c54
15 files changed, 94 insertions, 80 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7e5a078..f56f19b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,25 @@
+2003-05-09 Alan Modra <amodra@bigpond.net.au>
+
+ * expr.c (move_block_from_reg): Remove "size" parm. Localize vars.
+ Move code handling pieces not larger than a word to..
+ * function.c (assign_parms): ..here, but use change_address instead
+ of adjust_address and operand_subword, and expand_binop instead of
+ expand_shift. Adjust calls to move_block_from_reg.
+ * expr.h (move_block_from_reg): Update declaration.
+ (copy_blkmode_from_reg): Formatting.
+ * Makefile.in (function.o): Add $(OPTABS_H) to deps.
+ * config/alpha/alpha.c (alpha_setup_incoming_varargs): Adjust
+ move_block_from_reg calls.
+ * config/arc/arc.c (arc_setup_incoming_varargs): Likewise.
+ * config/i960/i960.c (i960_setup_incoming_varargs): Likewise.
+ * config/m32r/m32r.c (m32r_setup_incoming_varargs): Likewise.
+ * config/m88k/m88k.c (m88k_builtin_saveregsk): Likewise.
+ * config/mips/mips.c (mips_setup_incoming_varargs): Likewise.
+ * config/pa/pa.c (hppa_builtin_saveregs): Likewise.
+ * config/romp/romp.h (SETUP_INCOMING_VARARGS): Likewise.
+ * config/rs6000/rs6000.c (setup_incoming_varargs): Likewise.
+ * config/sh/sh.c (sh_builtin_saveregs): Likewise.
+
2003-05-08 DJ Delorie <dj@redhat.com>
* config/stormy16/stormy16.c (xstormy16_expand_builtin_va_arg): Fix
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index b4abda7..563649b 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1509,7 +1509,7 @@ varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_
output.h c-pragma.h toplev.h xcoffout.h debug.h $(GGC_H) $(TM_P_H) \
$(HASHTAB_H) $(TARGET_H) langhooks.h gt-varasm.h real.h
function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
- flags.h function.h $(EXPR_H) libfuncs.h $(REGS_H) hard-reg-set.h \
+ flags.h function.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(REGS_H) hard-reg-set.h \
insn-config.h $(RECOG_H) output.h toplev.h except.h $(HASHTAB_H) $(GGC_H) \
$(TM_P_H) langhooks.h gt-function.h
stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) flags.h \
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index b6538e6..e6a6410 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -6418,14 +6418,14 @@ alpha_setup_incoming_varargs(cum, mode, type, pretend_size, no_rtl)
plus_constant (virtual_incoming_args_rtx,
(cum + 6) * UNITS_PER_WORD));
set_mem_alias_set (tmp, set);
- move_block_from_reg (16 + cum, tmp, 6 - cum, (6 - cum) * UNITS_PER_WORD);
+ move_block_from_reg (16 + cum, tmp, 6 - cum);
tmp = gen_rtx_MEM (BLKmode,
plus_constant (virtual_incoming_args_rtx,
cum * UNITS_PER_WORD));
set_mem_alias_set (tmp, set);
move_block_from_reg (16 + (TARGET_FPREGS ? 32 : 0) + cum, tmp,
- 6 - cum, (6 - cum) * UNITS_PER_WORD);
+ 6 - cum);
}
*pretend_size = 12 * UNITS_PER_WORD;
}
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 5dcb105..faf8c1b 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -1,5 +1,5 @@
/* Subroutines used for code generation on the Argonaut ARC cpu.
- Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -831,9 +831,7 @@ arc_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
set_mem_alias_set (regblock, get_varargs_alias_set ());
set_mem_align (regblock, BITS_PER_WORD);
move_block_from_reg (first_reg_offset, regblock,
- MAX_ARC_PARM_REGS - first_reg_offset,
- ((MAX_ARC_PARM_REGS - first_reg_offset)
- * UNITS_PER_WORD));
+ MAX_ARC_PARM_REGS - first_reg_offset);
*pretend_size = ((MAX_ARC_PARM_REGS - first_reg_offset + align_slop)
* UNITS_PER_WORD);
diff --git a/gcc/config/i960/i960.c b/gcc/config/i960/i960.c
index 7436104..dc0353c 100644
--- a/gcc/config/i960/i960.c
+++ b/gcc/config/i960/i960.c
@@ -1,5 +1,5 @@
/* Subroutines used for code generation on intel 80960.
- Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+ Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
Contributed by Steven McGeady, Intel Corp.
Additional Work by Glenn Colon-Bonet, Jonathan Shapiro, Andy Wilson
@@ -2592,8 +2592,7 @@ i960_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
set_mem_alias_set (regblock, get_varargs_alias_set ());
set_mem_align (regblock, BITS_PER_WORD);
move_block_from_reg (first_reg, regblock,
- NPARM_REGS - first_reg,
- (NPARM_REGS - first_reg) * UNITS_PER_WORD);
+ NPARM_REGS - first_reg);
}
}
diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c
index a4e2ea2..c8f0c72 100644
--- a/gcc/config/m32r/m32r.c
+++ b/gcc/config/m32r/m32r.c
@@ -1,5 +1,5 @@
/* Subroutines used for code generation on the Mitsubishi M32R cpu.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -1405,8 +1405,7 @@ m32r_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
plus_constant (arg_pointer_rtx,
FIRST_PARM_OFFSET (0)));
set_mem_alias_set (regblock, get_varargs_alias_set ());
- move_block_from_reg (first_reg_offset, regblock,
- size, size * UNITS_PER_WORD);
+ move_block_from_reg (first_reg_offset, regblock, size);
*pretend_size = (size * UNITS_PER_WORD);
}
diff --git a/gcc/config/m88k/m88k.c b/gcc/config/m88k/m88k.c
index 33818a9..a27d8a3 100644
--- a/gcc/config/m88k/m88k.c
+++ b/gcc/config/m88k/m88k.c
@@ -1,6 +1,6 @@
/* Subroutines for insn-output.c for Motorola 88000.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002 Free Software Foundation, Inc.
+ 2001, 2002, 2003 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@mcc.com)
Currently maintained by (gcc@dg-rtp.dg.com)
@@ -2594,8 +2594,7 @@ m88k_builtin_saveregs ()
if (fixed < 8)
move_block_from_reg (2 + fixed,
adjust_address (addr, Pmode, fixed * UNITS_PER_WORD),
- 8 - fixed,
- UNITS_PER_WORD * (8 - fixed));
+ 8 - fixed);
/* Return the address of the save area, but don't put it in a
register. This fails when not optimizing and produces worse code
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index caebfbb..dd1f6a9 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -4815,7 +4815,7 @@ mips_setup_incoming_varargs (cum, mode, type, no_rtl)
MEM_SET_IN_STRUCT_P (mem, 1);
move_block_from_reg (local_cum.num_gprs + GP_ARG_FIRST, mem,
- gp_saved, gp_saved * UNITS_PER_WORD);
+ gp_saved);
}
if (fp_saved > 0)
{
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 601024a..82890fd 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -5403,7 +5403,7 @@ hppa_builtin_saveregs ()
-16));
set_mem_alias_set (dest, get_varargs_alias_set ());
set_mem_align (dest, BITS_PER_WORD);
- move_block_from_reg (23, dest, 4, 4 * UNITS_PER_WORD);
+ move_block_from_reg (23, dest, 4);
/* move_block_from_reg will emit code to store the argument registers
individually as scalar stores.
diff --git a/gcc/config/romp/romp.h b/gcc/config/romp/romp.h
index f81d88a..24fb1c2 100644
--- a/gcc/config/romp/romp.h
+++ b/gcc/config/romp/romp.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler, for ROMP chip.
- Copyright (C) 1989, 1991, 1993, 1995, 1996, 1998, 1999, 2000, 2001, 2002
- Free Software Foundation, Inc.
+ Copyright (C) 1989, 1991, 1993, 1995, 1996, 1998, 1999, 2000, 2001, 2002,
+ 2003 Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@nyu.edu)
This file is part of GNU CC.
@@ -662,7 +662,7 @@ struct rt_cargs {int gregs, fregs; };
gen_rtx_MEM (BLKmode, \
plus_constant (virtual_incoming_args_rtx, \
first_reg_offset * 4)), \
- 4 - first_reg_offset, (4 - first_reg_offset) * UNITS_PER_WORD); \
+ 4 - first_reg_offset); \
PRETEND_SIZE = (4 - first_reg_offset) * UNITS_PER_WORD; \
} \
}
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 4847a85..c5cfa14 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3805,10 +3805,8 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
set_mem_alias_set (mem, set);
set_mem_align (mem, BITS_PER_WORD);
- move_block_from_reg
- (GP_ARG_MIN_REG + first_reg_offset, mem,
- GP_ARG_NUM_REG - first_reg_offset,
- (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD);
+ move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
+ GP_ARG_NUM_REG - first_reg_offset);
}
/* Save FP registers if needed. */
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 24829f9..871cd62 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -1,6 +1,6 @@
/* Output routines for GCC for Hitachi / SuperH SH.
- Copyright (C) 1993, 1994, 1995, 1997, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1995, 1997, 1997, 1998, 1999, 2000, 2001, 2002,
+ 2003 Free Software Foundation, Inc.
Contributed by Steve Chamberlain (sac@cygnus.com).
Improved by Jim Wilson (wilson@cygnus.com).
@@ -5606,7 +5606,7 @@ sh_builtin_saveregs ()
move_block_from_reg (BASE_ARG_REG (SImode) + first_intreg,
adjust_address (regbuf, BLKmode,
n_floatregs * UNITS_PER_WORD),
- n_intregs, n_intregs * UNITS_PER_WORD);
+ n_intregs);
if (TARGET_SHMEDIA)
/* Return the address of the regbuf. */
diff --git a/gcc/expr.c b/gcc/expr.c
index 9f1c330..07d4b14 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2162,61 +2162,26 @@ move_block_to_reg (regno, x, nregs, mode)
}
/* Copy all or part of a BLKmode value X out of registers starting at REGNO.
- The number of registers to be filled is NREGS. SIZE indicates the number
- of bytes in the object X. */
+ The number of registers to be filled is NREGS. */
void
-move_block_from_reg (regno, x, nregs, size)
+move_block_from_reg (regno, x, nregs)
int regno;
rtx x;
int nregs;
- int size;
{
int i;
-#ifdef HAVE_store_multiple
- rtx pat;
- rtx last;
-#endif
- enum machine_mode mode;
if (nregs == 0)
return;
- /* If SIZE is that of a mode no bigger than a word, just use that
- mode's store operation. */
- if (size <= UNITS_PER_WORD
- && (mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0)) != BLKmode)
- {
- emit_move_insn (adjust_address (x, mode, 0), gen_rtx_REG (mode, regno));
- return;
- }
-
- /* Blocks smaller than a word on a BYTES_BIG_ENDIAN machine must be aligned
- to the left before storing to memory. Note that the previous test
- doesn't handle all cases (e.g. SIZE == 3). */
- if (size < UNITS_PER_WORD && BYTES_BIG_ENDIAN)
- {
- rtx tem = operand_subword (x, 0, 1, BLKmode);
- rtx shift;
-
- if (tem == 0)
- abort ();
-
- shift = expand_shift (LSHIFT_EXPR, word_mode,
- gen_rtx_REG (word_mode, regno),
- build_int_2 ((UNITS_PER_WORD - size)
- * BITS_PER_UNIT, 0), NULL_RTX, 0);
- emit_move_insn (tem, shift);
- return;
- }
-
/* See if the machine can do this with a store multiple insn. */
#ifdef HAVE_store_multiple
if (HAVE_store_multiple)
{
- last = get_last_insn ();
- pat = gen_store_multiple (x, gen_rtx_REG (word_mode, regno),
- GEN_INT (nregs));
+ rtx last = get_last_insn ();
+ rtx pat = gen_store_multiple (x, gen_rtx_REG (word_mode, regno),
+ GEN_INT (nregs));
if (pat)
{
emit_insn (pat);
diff --git a/gcc/expr.h b/gcc/expr.h
index 64ee6f1..9a73a71 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -414,7 +414,7 @@ extern void move_block_to_reg PARAMS ((int, rtx, int, enum machine_mode));
/* Copy all or part of a BLKmode value X out of registers starting at REGNO.
The number of registers to be filled is NREGS. */
-extern void move_block_from_reg PARAMS ((int, rtx, int, int));
+extern void move_block_from_reg PARAMS ((int, rtx, int));
/* Generate a non-consecutive group of registers represented by a PARALLEL. */
extern rtx gen_group_rtx PARAMS ((rtx));
@@ -433,7 +433,7 @@ extern void emit_group_store PARAMS ((rtx, rtx, int));
#ifdef TREE_CODE
/* Copy BLKmode object from a set of registers. */
-extern rtx copy_blkmode_from_reg PARAMS ((rtx,rtx,tree));
+extern rtx copy_blkmode_from_reg PARAMS ((rtx, rtx, tree));
#endif
/* Mark REG as holding a parameter for the next CALL_INSN. */
diff --git a/gcc/function.c b/gcc/function.c
index f9c0e42..ba23632 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -48,6 +48,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "except.h"
#include "function.h"
#include "expr.h"
+#include "optabs.h"
#include "libfuncs.h"
#include "regs.h"
#include "hard-reg-set.h"
@@ -4659,7 +4660,7 @@ assign_parms (fndecl)
else
move_block_from_reg (REGNO (entry_parm), validize_mem (stack_parm),
- partial, int_size_in_bytes (TREE_TYPE (parm)));
+ partial);
entry_parm = stack_parm;
}
@@ -4769,9 +4770,9 @@ assign_parms (fndecl)
if (GET_CODE (entry_parm) == REG
|| GET_CODE (entry_parm) == PARALLEL)
{
- int size_stored
- = CEIL_ROUND (int_size_in_bytes (TREE_TYPE (parm)),
- UNITS_PER_WORD);
+ int size = int_size_in_bytes (TREE_TYPE (parm));
+ int size_stored = CEIL_ROUND (size, UNITS_PER_WORD);
+ rtx mem;
/* Note that we will be storing an integral number of words.
So we have to be careful to ensure that we allocate an
@@ -4792,16 +4793,49 @@ assign_parms (fndecl)
else if (PARM_BOUNDARY % BITS_PER_WORD != 0)
abort ();
+ mem = validize_mem (stack_parm);
+
/* Handle calls that pass values in multiple non-contiguous
locations. The Irix 6 ABI has examples of this. */
if (GET_CODE (entry_parm) == PARALLEL)
- emit_group_store (validize_mem (stack_parm), entry_parm,
- int_size_in_bytes (TREE_TYPE (parm)));
+ emit_group_store (mem, entry_parm, size);
+
+ /* If SIZE is that of a mode no bigger than a word, just use
+ that mode's store operation. */
+ else if (size <= UNITS_PER_WORD)
+ {
+ enum machine_mode mode
+ = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
+
+ if (mode != BLKmode)
+ {
+ rtx reg = gen_rtx_REG (mode, REGNO (entry_parm));
+ emit_move_insn (change_address (mem, mode, 0), reg);
+ }
+
+ /* Blocks smaller than a word on a BYTES_BIG_ENDIAN
+ machine must be aligned to the left before storing
+ to memory. Note that the previous test doesn't
+ handle all cases (e.g. SIZE == 3). */
+ else if (size != UNITS_PER_WORD
+ && BYTES_BIG_ENDIAN)
+ {
+ rtx tem, x;
+ int by = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
+ rtx reg = gen_rtx_REG (word_mode, REGNO (entry_parm));
+
+ x = expand_binop (word_mode, ashl_optab, reg,
+ GEN_INT (by), 0, 1, OPTAB_WIDEN);
+ tem = change_address (mem, word_mode, 0);
+ emit_move_insn (tem, x);
+ }
+ else
+ move_block_from_reg (REGNO (entry_parm), mem,
+ size_stored / UNITS_PER_WORD);
+ }
else
- move_block_from_reg (REGNO (entry_parm),
- validize_mem (stack_parm),
- size_stored / UNITS_PER_WORD,
- int_size_in_bytes (TREE_TYPE (parm)));
+ move_block_from_reg (REGNO (entry_parm), mem,
+ size_stored / UNITS_PER_WORD);
}
SET_DECL_RTL (parm, stack_parm);
}