aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Wilson <wilson@gcc.gnu.org>1993-07-28 10:13:53 -0700
committerJim Wilson <wilson@gcc.gnu.org>1993-07-28 10:13:53 -0700
commit0040593d8684944f889602a4c3a18cf751408293 (patch)
tree41835f38ee795120fd0e6361929159ca3cc54eb1
parent8498efd0821d30f473d873bd4378484f914d9be5 (diff)
downloadgcc-0040593d8684944f889602a4c3a18cf751408293.zip
gcc-0040593d8684944f889602a4c3a18cf751408293.tar.gz
gcc-0040593d8684944f889602a4c3a18cf751408293.tar.bz2
(move_block_from_reg): New argument SIZE.
(move_block_from_reg): New argument SIZE. If SIZE less than word and BYTES_BIG_ENDIAN, shift block left to align it before storing it to memory. From-SVN: r5014
-rw-r--r--gcc/expr.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index b3addec..6a4a258 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -1460,17 +1460,38 @@ 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. */
+ The number of registers to be filled is NREGS. SIZE indicates the number
+ of bytes in the object X. */
+
void
-move_block_from_reg (regno, x, nregs)
+move_block_from_reg (regno, x, nregs, size)
int regno;
rtx x;
int nregs;
+ int size;
{
int i;
rtx pat, last;
+ /* Blocks smaller than a word on a BYTES_BIG_ENDIAN machine must be aligned
+ to the left before storing to memory. */
+ 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
last = get_last_insn ();