diff options
author | froydnj <froydnj@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-16 14:19:43 +0000 |
---|---|---|
committer | froydnj <froydnj@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-16 14:19:43 +0000 |
commit | c7e41aee2b459879f2e093101b0a4bd661a15563 (patch) | |
tree | 009d184c66e63f2861848fdff7492820d9952dc6 | |
parent | 74c33122cf8ee76de8e15ae016df830b7455a4d0 (diff) | |
download | gcc-c7e41aee2b459879f2e093101b0a4bd661a15563.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@166802 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/expr.c | 160 |
2 files changed, 71 insertions, 96 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 788be0aeab1..5f9d267cbd4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,12 @@ 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. (n_linker_options, n_assembler_options, n_preprocessor_options): Delete. diff --git a/gcc/expr.c b/gcc/expr.c index d2aefd5d763..889c34ef6d0 100644 --- a/gcc/expr.c +++ b/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; |