Commit d2348bd5 by DJ Delorie Committed by DJ Delorie

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
parent cc2f3fa6
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;
......
......@@ -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. */
......
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