Commit d824aea2 by Nathan Froyd Committed by Nathan Froyd

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
parent 69d540bd
2010-11-16 Nathan Froyd <froydnj@codesourcery.com> 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. * gcc.c (char_p): Define. Define a VEC of it.
(n_linker_options, n_assembler_options, n_preprocessor_options): (n_linker_options, n_assembler_options, n_preprocessor_options):
Delete. Delete.
...@@ -792,6 +792,50 @@ convert_modes (enum machine_mode mode, enum machine_mode oldmode, rtx x, int uns ...@@ -792,6 +792,50 @@ convert_modes (enum machine_mode mode, enum machine_mode oldmode, rtx x, int uns
return temp; 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_MAX_PIECES is the number of bytes at a time that we can
store efficiently. Due to internal GCC limitations, this is store efficiently. Due to internal GCC limitations, this is
MOVE_MAX_PIECES limited by the number of bytes GCC can represent 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, ...@@ -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)); = targetm.addr_space.address_mode (MEM_ADDR_SPACE (from));
rtx to_addr, from_addr = XEXP (from, 0); rtx to_addr, from_addr = XEXP (from, 0);
unsigned int max_size = MOVE_MAX_PIECES + 1; unsigned int max_size = MOVE_MAX_PIECES + 1;
enum machine_mode mode = VOIDmode, tmode;
enum insn_code icode; enum insn_code icode;
align = MIN (to ? MEM_ALIGN (to) : align, MEM_ALIGN (from)); 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, ...@@ -879,11 +922,11 @@ move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
if (!(data.autinc_from && data.autinc_to) if (!(data.autinc_from && data.autinc_to)
&& move_by_pieces_ninsns (len, align, max_size) > 2) && move_by_pieces_ninsns (len, align, max_size) > 2)
{ {
/* Find the mode of the largest move... */ /* Find the mode of the largest move...
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT); MODE might not be used depending on the definitions of the
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode)) USE_* macros below. */
if (GET_MODE_SIZE (tmode) < max_size) enum machine_mode mode ATTRIBUTE_UNUSED
mode = tmode; = widest_int_mode_for_size (max_size);
if (USE_LOAD_PRE_DECREMENT (mode) && data.reverse && ! data.autinc_from) 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, ...@@ -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); 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); align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
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 /* First move what we can in the largest integer mode, then go to
successively smaller modes. */ successively smaller modes. */
while (max_size > 1) while (max_size > 1)
{ {
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT); enum machine_mode mode = widest_int_mode_for_size (max_size);
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
if (GET_MODE_SIZE (tmode) < max_size)
mode = tmode;
if (mode == VOIDmode) if (mode == VOIDmode)
break; break;
...@@ -996,34 +1021,15 @@ move_by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align, ...@@ -996,34 +1021,15 @@ move_by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
unsigned int max_size) unsigned int max_size)
{ {
unsigned HOST_WIDE_INT n_insns = 0; 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) while (max_size > 1)
{ {
enum machine_mode mode = VOIDmode; enum machine_mode mode;
enum insn_code icode; enum insn_code icode;
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode = widest_int_mode_for_size (max_size);
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
if (GET_MODE_SIZE (tmode) < max_size)
mode = tmode;
if (mode == VOIDmode) if (mode == VOIDmode)
break; break;
...@@ -2258,7 +2264,7 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len, ...@@ -2258,7 +2264,7 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
unsigned HOST_WIDE_INT l; unsigned HOST_WIDE_INT l;
unsigned int max_size; unsigned int max_size;
HOST_WIDE_INT offset = 0; HOST_WIDE_INT offset = 0;
enum machine_mode mode, tmode; enum machine_mode mode;
enum insn_code icode; enum insn_code icode;
int reverse; int reverse;
/* cst is set but not used if LEGITIMATE_CONSTANT doesn't use it. */ /* 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, ...@@ -2272,22 +2278,7 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
: STORE_BY_PIECES_P (len, align))) : STORE_BY_PIECES_P (len, align)))
return 0; return 0;
tmode = mode_for_size (STORE_MAX_PIECES * BITS_PER_UNIT, MODE_INT, 1); align = alignment_for_piecewise_move (STORE_MAX_PIECES, align);
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 /* We would first store what we can in the largest integer mode, then go to
successively smaller modes. */ successively smaller modes. */
...@@ -2297,14 +2288,10 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len, ...@@ -2297,14 +2288,10 @@ can_store_by_pieces (unsigned HOST_WIDE_INT len,
reverse++) reverse++)
{ {
l = len; l = len;
mode = VOIDmode;
max_size = STORE_MAX_PIECES + 1; max_size = STORE_MAX_PIECES + 1;
while (max_size > 1) while (max_size > 1)
{ {
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode = widest_int_mode_for_size (max_size);
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
if (GET_MODE_SIZE (tmode) < max_size)
mode = tmode;
if (mode == VOIDmode) if (mode == VOIDmode)
break; break;
...@@ -2445,7 +2432,6 @@ store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED, ...@@ -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)); = targetm.addr_space.address_mode (MEM_ADDR_SPACE (data->to));
rtx to_addr = XEXP (data->to, 0); rtx to_addr = XEXP (data->to, 0);
unsigned int max_size = STORE_MAX_PIECES + 1; unsigned int max_size = STORE_MAX_PIECES + 1;
enum machine_mode mode = VOIDmode, tmode;
enum insn_code icode; enum insn_code icode;
data->offset = 0; data->offset = 0;
...@@ -2466,11 +2452,11 @@ store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED, ...@@ -2466,11 +2452,11 @@ store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED,
if (!data->autinc_to if (!data->autinc_to
&& move_by_pieces_ninsns (data->len, align, max_size) > 2) && move_by_pieces_ninsns (data->len, align, max_size) > 2)
{ {
/* Determine the main mode we'll be using. */ /* Determine the main mode we'll be using.
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT); MODE might not be used depending on the definitions of the
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode)) USE_* macros below. */
if (GET_MODE_SIZE (tmode) < max_size) enum machine_mode mode ATTRIBUTE_UNUSED
mode = tmode; = widest_int_mode_for_size (max_size);
if (USE_STORE_PRE_DECREMENT (mode) && data->reverse && ! data->autinc_to) 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, ...@@ -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); 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); align = alignment_for_piecewise_move (STORE_MAX_PIECES, align);
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 /* First store what we can in the largest integer mode, then go to
successively smaller modes. */ successively smaller modes. */
while (max_size > 1) while (max_size > 1)
{ {
for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT); enum machine_mode mode = widest_int_mode_for_size (max_size);
tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
if (GET_MODE_SIZE (tmode) < max_size)
mode = tmode;
if (mode == VOIDmode) if (mode == VOIDmode)
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment