aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorDavid Edelsohn <edelsohn@gnu.org>2004-08-12 15:05:38 +0000
committerDavid Edelsohn <dje@gcc.gnu.org>2004-08-12 11:05:38 -0400
commitf64d6991d42d47569e602a11dcbd21814d0a5026 (patch)
treeefaabf2ae2baf7a2843abb3d69518a7f30d1bee1 /gcc/expr.c
parentc597ef4eab9a2de9ad0b2187547ac9bac0b53132 (diff)
downloadgcc-f64d6991d42d47569e602a11dcbd21814d0a5026.zip
gcc-f64d6991d42d47569e602a11dcbd21814d0a5026.tar.gz
gcc-f64d6991d42d47569e602a11dcbd21814d0a5026.tar.bz2
expr.c (move_by_pieces): Set alignment for move to minimum of MOVE_MAX_PIECES mode alignment and the...
* expr.c (move_by_pieces): Set alignment for move to minimum of MOVE_MAX_PIECES mode alignment and the largest non-slow mode alignment, but not less than the original alignment. (move_by_pieces_ninsns): Same. (can_store_by_pieces): Similar for store with STORE_MAX_PIECES. (store_by_pieces_1): Same. From-SVN: r85875
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c79
1 files changed, 66 insertions, 13 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 282bb9a..7d216ae 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -925,9 +925,22 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
data.to_addr = copy_addr_to_reg (to_addr);
}
- if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
- || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
- align = MOVE_MAX * BITS_PER_UNIT;
+ tmode = mode_for_size (MOVE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
+ if (align >= GET_MODE_ALIGNMENT (tmode))
+ align = GET_MODE_ALIGNMENT (tmode);
+ else
+ {
+ enum machine_mode xmode;
+
+ for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT), xmode = tmode;
+ tmode != VOIDmode;
+ xmode = tmode, tmode = GET_MODE_WIDER_MODE (tmode))
+ if (GET_MODE_SIZE (tmode) > MOVE_MAX_PIECES
+ || SLOW_UNALIGNED_ACCESS (tmode, align))
+ break;
+
+ align = MAX (align, GET_MODE_ALIGNMENT (xmode));
+ }
/* First move what we can in the largest integer mode, then go to
successively smaller modes. */
@@ -992,14 +1005,28 @@ move_by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
unsigned int max_size)
{
unsigned HOST_WIDE_INT n_insns = 0;
+ enum machine_mode tmode;
- if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
- || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
- align = MOVE_MAX * BITS_PER_UNIT;
+ tmode = mode_for_size (MOVE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
+ if (align >= GET_MODE_ALIGNMENT (tmode))
+ align = GET_MODE_ALIGNMENT (tmode);
+ else
+ {
+ enum machine_mode tmode, xmode;
+
+ for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT), xmode = tmode;
+ tmode != VOIDmode;
+ xmode = tmode, tmode = GET_MODE_WIDER_MODE (tmode))
+ if (GET_MODE_SIZE (tmode) > MOVE_MAX_PIECES
+ || SLOW_UNALIGNED_ACCESS (tmode, align))
+ break;
+
+ align = MAX (align, GET_MODE_ALIGNMENT (xmode));
+ }
while (max_size > 1)
{
- enum machine_mode mode = VOIDmode, tmode;
+ enum machine_mode mode = VOIDmode;
enum insn_code icode;
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
@@ -1999,9 +2026,22 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
if (! STORE_BY_PIECES_P (len, align))
return 0;
- if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
- || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
- align = MOVE_MAX * BITS_PER_UNIT;
+ tmode = mode_for_size (STORE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
+ if (align >= GET_MODE_ALIGNMENT (tmode))
+ align = GET_MODE_ALIGNMENT (tmode);
+ else
+ {
+ enum machine_mode xmode;
+
+ for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT), xmode = tmode;
+ tmode != VOIDmode;
+ xmode = tmode, tmode = GET_MODE_WIDER_MODE (tmode))
+ if (GET_MODE_SIZE (tmode) > STORE_MAX_PIECES
+ || SLOW_UNALIGNED_ACCESS (tmode, align))
+ break;
+
+ align = MAX (align, GET_MODE_ALIGNMENT (xmode));
+ }
/* We would first store what we can in the largest integer mode, then go to
successively smaller modes. */
@@ -2201,9 +2241,22 @@ store_by_pieces_1 (struct store_by_pieces *data ATTRIBUTE_UNUSED,
data->to_addr = copy_addr_to_reg (to_addr);
}
- if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
- || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
- align = MOVE_MAX * BITS_PER_UNIT;
+ tmode = mode_for_size (STORE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1);
+ if (align >= GET_MODE_ALIGNMENT (tmode))
+ align = GET_MODE_ALIGNMENT (tmode);
+ else
+ {
+ enum machine_mode xmode;
+
+ for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT), xmode = tmode;
+ tmode != VOIDmode;
+ xmode = tmode, tmode = GET_MODE_WIDER_MODE (tmode))
+ if (GET_MODE_SIZE (tmode) > STORE_MAX_PIECES
+ || SLOW_UNALIGNED_ACCESS (tmode, align))
+ break;
+
+ align = MAX (align, GET_MODE_ALIGNMENT (xmode));
+ }
/* First store what we can in the largest integer mode, then go to
successively smaller modes. */