aboutsummaryrefslogtreecommitdiff
path: root/gcc/expmed.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r--gcc/expmed.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 883eff5b52b..6acc8956e26 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -2096,8 +2096,8 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
/* We'll be needing a couple extra algorithm structures now. */
- alg_in = (struct algorithm *)alloca (sizeof (struct algorithm));
- best_alg = (struct algorithm *)alloca (sizeof (struct algorithm));
+ alg_in = alloca (sizeof (struct algorithm));
+ best_alg = alloca (sizeof (struct algorithm));
/* If we have a group of zero bits at the low-order part of T, try
multiplying by the remaining bits and then doing a shift. */
@@ -2300,7 +2300,8 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
you should swap the two operands if OP0 would be constant. */
rtx
-expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, int unsignedp)
+expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
+ int unsignedp)
{
rtx const_op1 = op1;
@@ -2514,6 +2515,28 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, int unsignedp
}
}
+ if (GET_CODE (op0) == CONST_DOUBLE)
+ {
+ rtx temp = op0;
+ op0 = op1;
+ op1 = temp;
+ }
+
+ /* Expand x*2.0 as x+x. */
+ if (GET_CODE (op1) == CONST_DOUBLE
+ && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ REAL_VALUE_TYPE d;
+ REAL_VALUE_FROM_CONST_DOUBLE (d, op1);
+
+ if (REAL_VALUES_EQUAL (d, dconst2))
+ {
+ op0 = force_reg (GET_MODE (op0), op0);
+ return expand_binop (mode, add_optab, op0, op0,
+ target, unsignedp, OPTAB_LIB_WIDEN);
+ }
+ }
+
/* This used to use umul_optab if unsigned, but for non-widening multiply
there is no difference between signed and unsigned. */
op0 = expand_binop (mode,
@@ -2605,7 +2628,7 @@ choose_multiplier (unsigned HOST_WIDE_INT d, int n, int precision,
abort ();
if (mhigh_hi > 1 || mlow_hi > 1)
abort ();
- /* assert that mlow < mhigh. */
+ /* Assert that mlow < mhigh. */
if (! (mlow_hi < mhigh_hi || (mlow_hi == mhigh_hi && mlow_lo < mhigh_lo)))
abort ();
@@ -3801,7 +3824,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode,
build_int_2 (pre_shift, 0), NULL_RTX, unsignedp);
quotient = expand_mult (compute_mode, t1,
gen_int_mode (ml, compute_mode),
- NULL_RTX, 0);
+ NULL_RTX, 1);
insn = get_last_insn ();
set_unique_reg_note (insn,
@@ -4092,12 +4115,10 @@ make_tree (tree type, rtx x)
t = make_node (RTL_EXPR);
TREE_TYPE (t) = type;
-#ifdef POINTERS_EXTEND_UNSIGNED
/* If TYPE is a POINTER_TYPE, X might be Pmode with TYPE_MODE being
ptr_mode. So convert. */
- if (POINTER_TYPE_P (type) && GET_MODE (x) != TYPE_MODE (type))
+ if (POINTER_TYPE_P (type))
x = convert_memory_address (TYPE_MODE (type), x);
-#endif
RTL_EXPR_RTL (t) = x;
/* There are no insns to be output