diff options
author | DJ Delorie <dj@redhat.com> | 2005-05-31 20:20:13 -0400 |
---|---|---|
committer | DJ Delorie <dj@gcc.gnu.org> | 2005-05-31 20:20:13 -0400 |
commit | d2348bd59174b5f3c5c492da6190f80c3f6d745b (patch) | |
tree | ad8920def875a4093b66cd5ff53f14ecb758f32a /gcc | |
parent | cc2f3fa620d43b024f4cc1ea800e5246798e1f00 (diff) | |
download | gcc-d2348bd59174b5f3c5c492da6190f80c3f6d745b.zip gcc-d2348bd59174b5f3c5c492da6190f80c3f6d745b.tar.gz gcc-d2348bd59174b5f3c5c492da6190f80c3f6d745b.tar.bz2 |
expr.c (convert_move): When a partial_int requires multiple conversion steps...
* expr.c (convert_move): When a partial_int requires multiple
conversion steps, make sure successive steps convert the
intermediate value, not the original value.
* expmed.c (expand_mult): Convert partial_int multiplies to
shift/add combinations too.
* genmodes.c (mode_data): Add wider_2x.
(calc_wider_mode): Calculate twice-wider mode too.
(emit_mode_wider): Emit twice-wider mode too.
* machmode.h (mode_2xwider, GET_MODE_2XWIDER_MODE): New.
* expr.c (expand_expr_real_1): Use it for expanding
multiplies.
From-SVN: r100414
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/expmed.c | 2 | ||||
-rw-r--r-- | gcc/expr.c | 16 | ||||
-rw-r--r-- | gcc/genmodes.c | 37 | ||||
-rw-r--r-- | gcc/machmode.h | 3 |
5 files changed, 68 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9887402..2400635 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2005-05-31 DJ Delorie <dj@redhat.com> + + * expr.c (convert_move): When a partial_int requires multiple + conversion steps, make sure successive steps convert the + intermediate value, not the original value. + + * expmed.c (expand_mult): Convert partial_int multiplies to + shift/add combinations too. + + * genmodes.c (mode_data): Add wider_2x. + (calc_wider_mode): Calculate twice-wider mode too. + (emit_mode_wider): Emit twice-wider mode too. + * machmode.h (mode_2xwider, GET_MODE_2XWIDER_MODE): New. + * expr.c (expand_expr_real_1): Use it for expanding + multiplies. + 2005-05-31 Zdenek Dvorak <dvorakz@suse.cz> PR tree-optimization/21817 diff --git a/gcc/expmed.c b/gcc/expmed.c index c814233..ff8c278 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -3030,7 +3030,7 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, /* These are the operations that are potentially turned into a sequence of shifts and additions. */ - if (GET_MODE_CLASS (mode) == MODE_INT + if (SCALAR_INT_MODE_P (mode) && (unsignedp || !flag_trapv)) { HOST_WIDE_INT coeff = 0; @@ -466,19 +466,27 @@ convert_move (rtx to, rtx from, int unsignedp) } if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT) { + rtx new_from; enum machine_mode full_mode = smallest_mode_for_size (GET_MODE_BITSIZE (from_mode), MODE_INT); gcc_assert (sext_optab->handlers[full_mode][from_mode].insn_code != CODE_FOR_nothing); - emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code, - to, from, UNKNOWN); if (to_mode == full_mode) - return; + { + emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code, + to, from, UNKNOWN); + return; + } + + new_from = gen_reg_rtx (full_mode); + emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code, + new_from, from, UNKNOWN); /* else proceed to integer conversions below. */ from_mode = full_mode; + from = new_from; } /* Now both modes are integers. */ @@ -7747,7 +7755,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab; this_optab = zextend_p ? umul_widen_optab : smul_widen_optab; - if (mode == GET_MODE_WIDER_MODE (innermode)) + if (mode == GET_MODE_2XWIDER_MODE (innermode)) { if (this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) { diff --git a/gcc/genmodes.c b/gcc/genmodes.c index 6e282f3..74c71c9 100644 --- a/gcc/genmodes.c +++ b/gcc/genmodes.c @@ -64,6 +64,7 @@ struct mode_data struct mode_data *component; /* mode of components */ struct mode_data *wider; /* next wider mode */ + struct mode_data *wider_2x; /* 2x wider mode */ struct mode_data *contained; /* Pointer to list of modes that have this mode as a component. */ @@ -80,7 +81,7 @@ static struct mode_data *void_mode; static const struct mode_data blank_mode = { 0, "<unknown>", MAX_MODE_CLASS, -1U, -1U, -1U, -1U, - 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, "<unknown>", 0 }; @@ -717,6 +718,7 @@ calc_wider_mode (void) for (prev = 0, m = modes[c]; m; m = next) { m->wider = void_mode; + m->wider_2x = void_mode; /* this is nreverse */ next = m->next; @@ -951,6 +953,39 @@ emit_mode_wider (void) m->name); print_closer (); + print_decl ("unsigned char", "mode_2xwider", "NUM_MACHINE_MODES"); + + for_all_modes (c, m) + { + struct mode_data * m2; + + for (m2 = m; + m2 && m2 != void_mode; + m2 = m2->wider) + { + if (m2->bytesize < 2 * m->bytesize) + continue; + if (m->precision != (unsigned int) -1) + { + if (m2->precision != 2 * m->precision) + continue; + } + else + { + if (m2->precision != (unsigned int) -1) + continue; + } + + break; + } + if (m2 == void_mode) + m2 = 0; + tagged_printf ("%smode", + m2 ? m2->name : void_mode->name, + m->name); + } + + print_closer (); } static void diff --git a/gcc/machmode.h b/gcc/machmode.h index c978c0a..10016f8 100644 --- a/gcc/machmode.h +++ b/gcc/machmode.h @@ -115,6 +115,9 @@ extern const unsigned char mode_nunits[NUM_MACHINE_MODES]; extern const unsigned char mode_wider[NUM_MACHINE_MODES]; #define GET_MODE_WIDER_MODE(MODE) mode_wider[MODE] +extern const unsigned char mode_2xwider[NUM_MACHINE_MODES]; +#define GET_MODE_2XWIDER_MODE(MODE) mode_2xwider[MODE] + /* Return the mode for data of a given size SIZE and mode class CLASS. If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE. The value is BLKmode if no other mode is found. */ |