Backport from mainline: 2004-08-12 David Edelsohn * 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. Index: gcc/expr.c =================================================================== RCS file: /cvs/cvsfiles/devo/gcc/expr.c,v retrieving revision 1.500.2.4 diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.500.2.4 expr.c *** gcc/expr.c 31 Mar 2005 20:46:34 -0000 1.500.2.4 --- gcc/expr.c 11 May 2005 08:54:22 -0000 *************** move_by_pieces (rtx to, rtx from, unsign *** 1144,1152 **** 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; /* First move what we can in the largest integer mode, then go to successively smaller modes. */ --- 1144,1165 ---- data.to_addr = copy_addr_to_reg (to_addr); } ! 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. */ *************** move_by_pieces_ninsns (unsigned HOST_WID *** 1211,1224 **** { unsigned HOST_WIDE_INT n_insns = 0; unsigned HOST_WIDE_INT max_size = MOVE_MAX + 1; ! if (! SLOW_UNALIGNED_ACCESS (word_mode, align) ! || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT) ! align = MOVE_MAX * BITS_PER_UNIT; while (max_size > 1) { ! enum machine_mode mode = VOIDmode, tmode; enum insn_code icode; for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT); --- 1224,1251 ---- { unsigned HOST_WIDE_INT n_insns = 0; unsigned HOST_WIDE_INT max_size = MOVE_MAX + 1; + enum machine_mode tmode; ! 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; enum insn_code icode; for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT); *************** can_store_by_pieces (unsigned HOST_WIDE_ *** 2272,2280 **** 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; /* We would first store what we can in the largest integer mode, then go to successively smaller modes. */ --- 2299,2320 ---- if (! STORE_BY_PIECES_P (len, align)) return 0; ! 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. */ *************** store_by_pieces_1 (struct store_by_piece *** 2477,2485 **** 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; /* First store what we can in the largest integer mode, then go to successively smaller modes. */ --- 2517,2538 ---- data->to_addr = copy_addr_to_reg (to_addr); } ! 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. */