aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2005-05-31 20:20:13 -0400
committerDJ Delorie <dj@gcc.gnu.org>2005-05-31 20:20:13 -0400
commitd2348bd59174b5f3c5c492da6190f80c3f6d745b (patch)
treead8920def875a4093b66cd5ff53f14ecb758f32a /gcc/expr.c
parentcc2f3fa620d43b024f4cc1ea800e5246798e1f00 (diff)
downloadgcc-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/expr.c')
-rw-r--r--gcc/expr.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 459c248..5cb883a 100644
--- a/gcc/expr.c
+++ b/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)
{