diff options
author | Jim Wilson <wilson@gcc.gnu.org> | 1993-07-28 10:13:53 -0700 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 1993-07-28 10:13:53 -0700 |
commit | 0040593d8684944f889602a4c3a18cf751408293 (patch) | |
tree | 41835f38ee795120fd0e6361929159ca3cc54eb1 | |
parent | 8498efd0821d30f473d873bd4378484f914d9be5 (diff) | |
download | gcc-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.c | 25 |
1 files changed, 23 insertions, 2 deletions
@@ -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 (); |