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
This commit is contained in:
parent
cc2f3fa620
commit
d2348bd591
5 changed files with 68 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
16
gcc/expr.c
16
gcc/expr.c
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Add table
Reference in a new issue