X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fexpr.c;h=56a6249cb50a72ce1d1702731fdfb4efd7264807;hb=f3f03d1ef01ae945da02a8d1fc3972459b1df5c3;hp=e994f938b6fe7f765a7880992d87ae2bc8b41b9e;hpb=db5b2472c14114946acf355de056b70396bff658;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/expr.c b/gcc/expr.c index e994f938b6f..56a6249cb50 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,10 +2264,11 @@ 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; - rtx cst; + /* cst is set but not used if LEGITIMATE_CONSTANT doesn't use it. */ + rtx cst ATTRIBUTE_UNUSED; if (len == 0) return 1; @@ -2271,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. */ @@ -2296,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; @@ -2444,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; @@ -2465,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) { @@ -2491,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; @@ -4259,11 +4228,16 @@ expand_assignment (tree to, tree from, bool nontemporal) to_rtx = expand_normal (tem); /* If the bitfield is volatile, we want to access it in the - field's mode, not the computed mode. */ - if (volatilep - && GET_CODE (to_rtx) == MEM - && flag_strict_volatile_bitfields > 0) - to_rtx = adjust_address (to_rtx, mode1, 0); + field's mode, not the computed mode. + If a MEM has VOIDmode (external with incomplete type), + use BLKmode for it instead. */ + if (MEM_P (to_rtx)) + { + if (volatilep && flag_strict_volatile_bitfields > 0) + to_rtx = adjust_address (to_rtx, mode1, 0); + else if (GET_MODE (to_rtx) == VOIDmode) + to_rtx = adjust_address (to_rtx, BLKmode, 0); + } if (offset != 0) { @@ -8753,7 +8727,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, } align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), get_object_alignment (exp, BIGGEST_ALIGNMENT)); - op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_NORMAL); + op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_SUM); op0 = convert_memory_address_addr_space (address_mode, op0, as); if (!integer_zerop (TREE_OPERAND (exp, 1))) { @@ -9012,11 +8986,16 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, /* If the bitfield is volatile, we want to access it in the - field's mode, not the computed mode. */ - if (volatilep - && GET_CODE (op0) == MEM - && flag_strict_volatile_bitfields > 0) - op0 = adjust_address (op0, mode1, 0); + field's mode, not the computed mode. + If a MEM has VOIDmode (external with incomplete type), + use BLKmode for it instead. */ + if (MEM_P (op0)) + { + if (volatilep && flag_strict_volatile_bitfields > 0) + op0 = adjust_address (op0, mode1, 0); + else if (GET_MODE (op0) == VOIDmode) + op0 = adjust_address (op0, BLKmode, 0); + } mode2 = CONSTANT_P (op0) ? TYPE_MODE (TREE_TYPE (tem)) : GET_MODE (op0); @@ -10311,7 +10290,7 @@ build_personality_function (const char *lang) tree decl, type; char *name; - switch (targetm.except_unwind_info ()) + switch (targetm.except_unwind_info (&global_options)) { case UI_NONE: return NULL;