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> 2005-05-31 Zdenek Dvorak <dvorakz@suse.cz>
PR tree-optimization/21817 PR tree-optimization/21817
......
...@@ -3030,7 +3030,7 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, ...@@ -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 /* These are the operations that are potentially turned into a sequence
of shifts and additions. */ of shifts and additions. */
if (GET_MODE_CLASS (mode) == MODE_INT if (SCALAR_INT_MODE_P (mode)
&& (unsignedp || !flag_trapv)) && (unsignedp || !flag_trapv))
{ {
HOST_WIDE_INT coeff = 0; HOST_WIDE_INT coeff = 0;
......
...@@ -466,19 +466,27 @@ convert_move (rtx to, rtx from, int unsignedp) ...@@ -466,19 +466,27 @@ convert_move (rtx to, rtx from, int unsignedp)
} }
if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT) if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)
{ {
rtx new_from;
enum machine_mode full_mode enum machine_mode full_mode
= smallest_mode_for_size (GET_MODE_BITSIZE (from_mode), MODE_INT); = smallest_mode_for_size (GET_MODE_BITSIZE (from_mode), MODE_INT);
gcc_assert (sext_optab->handlers[full_mode][from_mode].insn_code gcc_assert (sext_optab->handlers[full_mode][from_mode].insn_code
!= CODE_FOR_nothing); != CODE_FOR_nothing);
emit_unop_insn (sext_optab->handlers[full_mode][from_mode].insn_code,
to, from, UNKNOWN);
if (to_mode == full_mode) 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. */ /* else proceed to integer conversions below. */
from_mode = full_mode; from_mode = full_mode;
from = new_from;
} }
/* Now both modes are integers. */ /* Now both modes are integers. */
...@@ -7747,7 +7755,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, ...@@ -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; optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
this_optab = zextend_p ? umul_widen_optab : smul_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) if (this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
{ {
......
...@@ -64,6 +64,7 @@ struct mode_data ...@@ -64,6 +64,7 @@ struct mode_data
struct mode_data *component; /* mode of components */ struct mode_data *component; /* mode of components */
struct mode_data *wider; /* next wider mode */ 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 struct mode_data *contained; /* Pointer to list of modes that have
this mode as a component. */ this mode as a component. */
...@@ -80,7 +81,7 @@ static struct mode_data *void_mode; ...@@ -80,7 +81,7 @@ static struct mode_data *void_mode;
static const struct mode_data blank_mode = { static const struct mode_data blank_mode = {
0, "<unknown>", MAX_MODE_CLASS, 0, "<unknown>", MAX_MODE_CLASS,
-1U, -1U, -1U, -1U, -1U, -1U, -1U, -1U,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
"<unknown>", 0 "<unknown>", 0
}; };
...@@ -717,6 +718,7 @@ calc_wider_mode (void) ...@@ -717,6 +718,7 @@ calc_wider_mode (void)
for (prev = 0, m = modes[c]; m; m = next) for (prev = 0, m = modes[c]; m; m = next)
{ {
m->wider = void_mode; m->wider = void_mode;
m->wider_2x = void_mode;
/* this is nreverse */ /* this is nreverse */
next = m->next; next = m->next;
...@@ -951,6 +953,39 @@ emit_mode_wider (void) ...@@ -951,6 +953,39 @@ emit_mode_wider (void)
m->name); m->name);
print_closer (); 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 static void
......
...@@ -115,6 +115,9 @@ extern const unsigned char mode_nunits[NUM_MACHINE_MODES]; ...@@ -115,6 +115,9 @@ extern const unsigned char mode_nunits[NUM_MACHINE_MODES];
extern const unsigned char mode_wider[NUM_MACHINE_MODES]; extern const unsigned char mode_wider[NUM_MACHINE_MODES];
#define GET_MODE_WIDER_MODE(MODE) mode_wider[MODE] #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. /* 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. 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. */ 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