expr.c (alignment_for_piecewise_move): New function.
* expr.c (alignment_for_piecewise_move): New function. (widest_int_mode_for_size): New function. (move_by_pieces, move_by_pieces_ninsns): Call them. (can_store_by_pieces, store_by_pieces_1): Likewise. From-SVN: r166802
This commit is contained in:
parent
69d540bdc7
commit
d824aea207
2 changed files with 71 additions and 96 deletions
|
@ -1,3 +1,10 @@
|
|||
2010-11-16 Nathan Froyd <froydnj@codesourcery.com>
|
||||
|
||||
* expr.c (alignment_for_piecewise_move): New function.
|
||||
(widest_int_mode_for_size): New function.
|
||||
(move_by_pieces, move_by_pieces_ninsns): Call them.
|
||||
(can_store_by_pieces, store_by_pieces_1): Likewise.
|
||||
|
||||
2010-11-16 Nathan Froyd <froydnj@codesourcery.com>
|
||||
|
||||
* gcc.c (char_p): Define. Define a VEC of it.
|
||||
|
|
160
gcc/expr.c
160
gcc/expr.c
|
@ -792,6 +792,50 @@ convert_modes (enum machine_mode mode, enum machine_mode oldmode, rtx x, int uns
|
|||
return temp;
|
||||
}
|
||||
|
||||
/* Return the largest alignment we can use for doing a move (or store)
|
||||
of MAX_PIECES. ALIGN is the largest alignment we could use. */
|
||||
|
||||
static unsigned int
|
||||
alignment_for_piecewise_move (unsigned int max_pieces, unsigned int align)
|
||||
{
|
||||
enum machine_mode tmode;
|
||||
|
||||
tmode = mode_for_size (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) > max_pieces
|
||||
|| SLOW_UNALIGNED_ACCESS (tmode, align))
|
||||
break;
|
||||
|
||||
align = MAX (align, GET_MODE_ALIGNMENT (xmode));
|
||||
}
|
||||
|
||||
return align;
|
||||
}
|
||||
|
||||
/* Return the widest integer mode no wider than SIZE. If no such mode
|
||||
can be found, return VOIDmode. */
|
||||
|
||||
static enum machine_mode
|
||||
widest_int_mode_for_size (unsigned int size)
|
||||
{
|
||||
enum machine_mode tmode, mode = VOIDmode;
|
||||
|
||||
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
|
||||
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
|
||||
if (GET_MODE_SIZE (tmode) < size)
|
||||
mode = tmode;
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
/* STORE_MAX_PIECES is the number of bytes at a time that we can
|
||||
store efficiently. Due to internal GCC limitations, this is
|
||||
MOVE_MAX_PIECES limited by the number of bytes GCC can represent
|
||||
|
@ -831,7 +875,6 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
|
|||
= targetm.addr_space.address_mode (MEM_ADDR_SPACE (from));
|
||||
rtx to_addr, from_addr = XEXP (from, 0);
|
||||
unsigned int max_size = MOVE_MAX_PIECES + 1;
|
||||
enum machine_mode mode = VOIDmode, tmode;
|
||||
enum insn_code icode;
|
||||
|
||||
align = MIN (to ? MEM_ALIGN (to) : align, MEM_ALIGN (from));
|
||||
|
@ -879,11 +922,11 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
|
|||
if (!(data.autinc_from && data.autinc_to)
|
||||
&& move_by_pieces_ninsns (len, align, max_size) > 2)
|
||||
{
|
||||
/* Find the mode of the largest move... */
|
||||
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
|
||||
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
|
||||
if (GET_MODE_SIZE (tmode) < max_size)
|
||||
mode = tmode;
|
||||
/* Find the mode of the largest move...
|
||||
MODE might not be used depending on the definitions of the
|
||||
USE_* macros below. */
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED
|
||||
= widest_int_mode_for_size (max_size);
|
||||
|
||||
if (USE_LOAD_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_from)
|
||||
{
|
||||
|
@ -917,32 +960,14 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
|
|||
data.to_addr = copy_to_mode_reg (to_addr_mode, 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));
|
||||
}
|
||||
align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
|
||||
|
||||
/* First move what we can in the largest integer mode, then go to
|
||||
successively smaller modes. */
|
||||
|
||||
while (max_size > 1)
|
||||
{
|
||||
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
|
||||
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
|
||||
if (GET_MODE_SIZE (tmode) < max_size)
|
||||
mode = tmode;
|
||||
enum machine_mode mode = widest_int_mode_for_size (max_size);
|
||||
|
||||
if (mode == VOIDmode)
|
||||
break;
|
||||
|
@ -996,34 +1021,15 @@ 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;
|
||||
|
||||
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));
|
||||
}
|
||||
align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
|
||||
|
||||
while (max_size > 1)
|
||||
{
|
||||
enum machine_mode mode = VOIDmode;
|
||||
enum machine_mode mode;
|
||||
enum insn_code icode;
|
||||
|
||||
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
|
||||
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
|
||||
if (GET_MODE_SIZE (tmode) < max_size)
|
||||
mode = tmode;
|
||||
mode = widest_int_mode_for_size (max_size);
|
||||
|
||||
if (mode == VOIDmode)
|
||||
break;
|
||||
|
@ -2258,7 +2264,7 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
|
|||
unsigned HOST_WIDE_INT l;
|
||||
unsigned int max_size;
|
||||
HOST_WIDE_INT offset = 0;
|
||||
enum machine_mode mode, tmode;
|
||||
enum machine_mode mode;
|
||||
enum insn_code icode;
|
||||
int reverse;
|
||||
/* cst is set but not used if LEGITIMATE_CONSTANT doesn't use it. */
|
||||
|
@ -2272,22 +2278,7 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
|
|||
: 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));
|
||||
}
|
||||
align = alignment_for_piecewise_move (STORE_MAX_PIECES, align);
|
||||
|
||||
/* We would first store what we can in the largest integer mode, then go to
|
||||
successively smaller modes. */
|
||||
|
@ -2297,14 +2288,10 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
|
|||
reverse++)
|
||||
{
|
||||
l = len;
|
||||
mode = VOIDmode;
|
||||
max_size = STORE_MAX_PIECES + 1;
|
||||
while (max_size > 1)
|
||||
{
|
||||
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
|
||||
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
|
||||
if (GET_MODE_SIZE (tmode) < max_size)
|
||||
mode = tmode;
|
||||
mode = widest_int_mode_for_size (max_size);
|
||||
|
||||
if (mode == VOIDmode)
|
||||
break;
|
||||
|
@ -2445,7 +2432,6 @@ store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED,
|
|||
= targetm.addr_space.address_mode (MEM_ADDR_SPACE (data->to));
|
||||
rtx to_addr = XEXP (data->to, 0);
|
||||
unsigned int max_size = STORE_MAX_PIECES + 1;
|
||||
enum machine_mode mode = VOIDmode, tmode;
|
||||
enum insn_code icode;
|
||||
|
||||
data->offset = 0;
|
||||
|
@ -2466,11 +2452,11 @@ store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED,
|
|||
if (!data->autinc_to
|
||||
&& move_by_pieces_ninsns (data->len, align, max_size) > 2)
|
||||
{
|
||||
/* Determine the main mode we'll be using. */
|
||||
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
|
||||
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
|
||||
if (GET_MODE_SIZE (tmode) < max_size)
|
||||
mode = tmode;
|
||||
/* Determine the main mode we'll be using.
|
||||
MODE might not be used depending on the definitions of the
|
||||
USE_* macros below. */
|
||||
enum machine_mode mode ATTRIBUTE_UNUSED
|
||||
= widest_int_mode_for_size (max_size);
|
||||
|
||||
if (USE_STORE_PRE_DECREMENT (mode) && data->reverse && ! data->autinc_to)
|
||||
{
|
||||
|
@ -2492,32 +2478,14 @@ store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED,
|
|||
data->to_addr = copy_to_mode_reg (to_addr_mode, 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));
|
||||
}
|
||||
align = alignment_for_piecewise_move (STORE_MAX_PIECES, align);
|
||||
|
||||
/* First store what we can in the largest integer mode, then go to
|
||||
successively smaller modes. */
|
||||
|
||||
while (max_size > 1)
|
||||
{
|
||||
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
|
||||
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
|
||||
if (GET_MODE_SIZE (tmode) < max_size)
|
||||
mode = tmode;
|
||||
enum machine_mode mode = widest_int_mode_for_size (max_size);
|
||||
|
||||
if (mode == VOIDmode)
|
||||
break;
|
||||
|
|
Loading…
Add table
Reference in a new issue